Python Socket双向传输Excel文件程序阻塞问题求助
问题根本原因
- 核心阻塞点:TCP是字节流协议,没有内置消息边界,你当前服务端接收输入文件的逻辑是
循环调用recv()直到返回空值,但recv()返回空只有在对方主动关闭连接的时候才会触发。客户端发送完输入文件后没有关闭写通道,也没有发送传输结束标记,服务端会一直卡在接收文件的recv()调用处,永远执行不到后面的模型代码。 - 附带bug:服务端回传结果文件前读取文件大小的代码写错了,
outfilesize = os.path.getsize(filename)这里的filename是输入文件的名称,你实际要读取的是输出文件outfilename的大小,会导致回传的文件大小参数错误,后续接收结果也会出错。
可行解决思路
方案1:按预先传输的文件大小精确接收(推荐)
你在传输文件前已经发送了文件大小参数,直接用这个参数控制接收的字节数即可,不需要等空返回:
服务端修改接收输入文件的代码
received_bytes = 0 with open(filename, "wb") as f: while received_bytes < filesize: # 每次最多读剩下需要的字节数,避免读多了把后续内容读走 bytes_read = client_socket.recv(min(BUFFER_SIZE, filesize - received_bytes)) if not bytes_read: # 对方提前断开连接,可按需添加异常处理逻辑 break f.write(bytes_read) received_bytes += len(bytes_read)
客户端修改接收结果文件的代码
out_received_bytes = 0 with open(out_filename, "wb") as h: while out_received_bytes < out_filesize: out_bytes_read = s.recv(min(BUFFER_SIZE, out_filesize - out_received_bytes)) if not out_bytes_read: break h.write(out_bytes_read) out_received_bytes += len(out_bytes_read)
修复服务端文件大小读取错误
把outfilesize = os.path.getsize(filename)修改为:
outfilesize = os.path.getsize(outfilename)
方案2:客户端发完文件后半关闭写通道
如果不想调整接收逻辑,客户端发完输入文件后调用半关闭方法,只关闭写通道,保留读通道用来接收结果即可:
客户端发完输入文件后添加代码:
# 关闭写通道,服务端recv会返回空,正常退出接收循环 s.shutdown(socket.SHUT_WR)
注意该方案仅适用于发完输入文件后不需要再向服务端发送其他数据的场景。
内容的提问来源于stack exchange,提问作者user16906647
相关产品推荐
相关产品推荐

