You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Socket多文件接收报错:ValueError无效二进制字面量求助

解决Python Socket文件接收时的ValueError问题

这个报错一眼就能看出核心问题:你的服务器端代码正尝试把一段HTML文本当成二进制数字字符串来转换整数,这显然和你预期的「文件名长度数据」完全不搭边。咱们一步步拆解原因和解决办法:

最可能的元凶:连错了服务器地址/端口

报错里的<DOCTYPE html...>是标准的HTTP响应头,这说明你的客户端socket意外连接到了一个Web服务器(比如80/8080端口的服务),而非你自己写的Socket文件服务器。对方返回的HTML被你的服务器当成了「文件名长度的二进制串」,自然会触发invalid literal for int() with base 2错误。

解决办法

立刻检查客户端代码里的s.connect(...)语句,确认IP地址和端口号完全匹配你的Socket服务器的监听地址。比如如果你的服务器是localhost:9999,就绝对不能写成localhost:80或者其他Web服务常用端口。

次要可能:TCP粘包/收发逻辑不严谨

如果确认连接地址没问题,那就要排查收发数据的逻辑了——TCP是流式协议,如果你没严格按照约定的格式收发,很可能导致数据串混,比如把后续的文件名甚至之前的残留数据当成了长度串。

客户端发送逻辑修正

你当前的代码有几个潜在坑:

  1. 直接发送字符串而不编码(Python3的send只接受bytes类型)
  2. 用len(filename)算长度(如果文件名包含中文等多字节字符,字符串长度≠字节长度)

修正后的客户端发送代码:

import os
import socket

# 假设s是已经建立好的socket连接
path = "./your_directory"
for files in os.listdir(path):
    filename = files
    # 先把文件名转成字节串,按字节长度计算(避免多字节字符坑)
    filename_bytes = filename.encode('utf-8')
    filename_len = len(filename_bytes)
    # 转成16位二进制字符串,再编码成字节发送
    size_str = bin(filename_len)[2:].zfill(16)
    s.send(size_str.encode('utf-8'))
    # 发送文件名的字节串
    s.send(filename_bytes)
    # 后续发送文件内容的逻辑...

服务器端接收逻辑修正

服务器端要严格先收固定16字节的长度串,再按长度收文件名:

import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 9999))
server_socket.listen(5)

while True:
    client_sock, addr = server_socket.accept()
    print(f"连接来自:{addr}")
    while True:
        # 先接收16字节的长度串
        size_data = client_sock.recv(16)
        if not size_data:
            # 客户端断开连接
            break
        try:
            size_str = size_data.decode('utf-8')
            filename_len = int(size_str, 2)
        except ValueError as e:
            print(f"无效的长度数据:{e},收到的原始数据:{size_data}")
            client_sock.close()
            break
        # 按约定长度接收文件名
        filename_data = client_sock.recv(filename_len)
        if not filename_data:
            break
        filename = filename_data.decode('utf-8')
        print(f"收到文件名:{filename}")
        # 后续接收文件内容的逻辑...
    client_sock.close()

最后排查点:残留连接/未清空缓冲区

如果之前的测试中没有正确关闭socket连接,可能导致缓冲区残留旧数据,下次通信时干扰新数据。解决办法是每次通信完成后,客户端和服务器都要调用s.close()关闭连接,或者在每次接收前确保缓冲区已清空。


内容的提问来源于stack exchange,提问作者zatip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:22:10