文件传输程序循环无法终止求助:已接收文件但无法回到外层循环
文件传输程序内层循环无法终止的解决办法
问题原因
TCP属于流式传输协议,没有明确的“数据包边界”。你的代码中,客户端发送完所有文件数据后,服务器端的recv(4096)会一直阻塞等待新数据——因为它无法判断文件是否已经传输完毕,只有当连接被关闭时才会返回空数据触发break。而你的客户端发送完文件后并未关闭连接或发送结束信号,导致服务器内层循环一直卡在等待状态。
解决方案
方案1:传输前先发送文件大小
让客户端先把文件的总大小发给服务器,服务器根据已接收的字节数判断是否传输完成:
服务器端代码修改
# server side while True: cmd = input("enter msg command :") client_socket.send(cmd.encode()) if cmd.startswith("download"): filename = cmd.strip("download ") # 接收文件大小 file_size = int(client_socket.recv(1024).decode()) received_bytes = 0 with open(filename, 'wb') as f: print("Downloading file...") while received_bytes < file_size: data = client_socket.recv(4096) if not data: break f.write(data) received_bytes += len(data) print("Successfully downloaded")
客户端代码修改
# client side import os while True: command = s.recv(1024) command = command.decode() if command.startswith("download"): print("True\n") filename = command.strip("download ") # 获取并发送文件大小 file_size = os.path.getsize(filename) s.send(str(file_size).encode()) with open(filename,'rb') as f: print("file sending.....") while True: data = f.read(4096) if not data: break s.sendall(data) print("file has sent")
方案2:发送结束标记
客户端发送完文件后,发送一个约定好的特殊标记,服务器收到该标记后终止循环:
服务器端代码修改
# server side while True: cmd = input("enter msg command :") client_socket.send(cmd.encode()) if cmd.startswith("download"): filename = cmd.strip("download ") with open(filename, 'wb') as f: print("Downloading file...") while True: data = client_socket.recv(4096) # 约定的结束标记,确保不会和文件内容冲突 if data == b'__FILE_TRANSFER_DONE__': break f.write(data) print("Successfully downloaded")
客户端代码修改
# client side while True: command = s.recv(1024) command = command.decode() if command.startswith("download"): print("True\n") filename = command.strip("download ") with open(filename,'rb') as f: print("file sending.....") while True: data = f.read(4096) if not data: # 发送结束标记 s.sendall(b'__FILE_TRANSFER_DONE__') break s.sendall(data) print("file has sent")
注意事项
- 方案1中,如果传输超大文件,建议用
struct模块序列化文件大小(避免字符串编码的长度限制)。 - 方案2中,要确保结束标记不会出现在正常文件内容中,否则会导致提前终止循环。
内容的提问来源于stack exchange,提问作者jouini hakim
相关产品推荐
相关产品推荐

