Python Socket编程报错10061或服务器无法接收数据问题排查
问题根因定位
1. 服务端逻辑缺陷
s.accept()仅在程序启动时执行1次,只能接受1次客户端连接。但客户端每次循环都会新建独立的Socket连接请求,第二次及以后的连接请求服务端根本不会处理,直接被系统拒绝- 服务端绑定
localhost时,仅监听127.0.0.1回环地址,使用本机实际IP访问时,请求无法被监听到,自然会返回连接拒绝错误
2. 客户端逻辑缺陷
- 计时逻辑完全错位:
a = datetime.datetime.now()写在sendall()执行之后,统计的根本不是实际发送耗时 - 文件只读了一次:
file_to_send.read(1024)第一次读完后文件指针已经到末尾,第二次及以后循环读取到的是空数据 - 每次循环新建的Socket没有主动关闭,TCP连接处于TIME_WAIT状态时端口占用会导致后续连接失败
解决方案
第一步:修改服务端逻辑
- 将
accept()放到循环内部,每次处理完一次连接就关闭,等待下一次新的连接 - 绑定地址改为
0.0.0.0,允许所有IP地址访问,这样不管是localhost还是本机实际IP都能正常连接
修改后的完整服务端代码:
import socket import time import datetime import filecmp HOST = '0.0.0.0' PORT = 9100 n = 1 x = 0 average_list = [] file_comparison = "send.txt" s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind((HOST,PORT)) s.listen(1) print('I am ready for any client side request \n') while n <= 100: conn, addr = s.accept() data = conn.recv(1024) file = 'receive1.txt' print('I am starting receiving file', file,'for the',n,'th time') a = datetime.datetime.now() f = open(file, 'wb') f.write(data) f.close() print('I am finishing receiving file', file,'for the',n,'th time') b = datetime.datetime.now() millidelta = (b - a).total_seconds() * 1000 average_list.append(millidelta) real_average = sum(average_list) / n print('The time used in milliseconds to receive',file,'for the',n,'th time','is:',millidelta,'milliseconds') print('The average time to receive',file,'in milliseconds is:',real_average) if filecmp.cmp(file,file_comparison,shallow=False): x = x+1 conn.close() n=n + 1 s.close() print('I am done \n') print('Total errors: ',x,'out of',n-1 )
第二步:修改客户端逻辑
- 每次循环读取文件前将指针重置到文件开头,避免读取空内容
- 调整计时逻辑,将开始计时放在
sendall()之前 - 每次发送完成后立刻关闭当前Socket,释放端口资源
修改后的完整客户端代码:
import socket import datetime import filecmp host = 'localhost' port = 9100 fileName = "send.txt" n = 1 average_list = [] file_to_send = open(fileName,'rb') while n <= 100: file_to_send.seek(0) data = file_to_send.read(1024) s=socket.socket() print('I am connecting to server side:',host,'\n') s.connect((host,port)) print('I am sending file',fileName,'for the',n,'th time') a = datetime.datetime.now() s.sendall(data) b = datetime.datetime.now() print('I am finishing sending file',fileName,'for the',n,'th time') millidelta = (b - a).total_seconds() * 1000 average_list.append(millidelta) real_average = sum(average_list) / n print('The time used in milliseconds to send',fileName,'for the',n,'th time','is:',millidelta,'milliseconds') print('The average time to send',fileName,'in milliseconds is:',real_average) s.close() n = n + 1 file_to_send.close() print('I am done')
额外排查步骤
如果修改后仍有连接拒绝问题,可按以下步骤验证:
- 检查系统防火墙是否开放了9100端口的TCP出入规则
- 执行
netstat -ano | findstr "9100"命令确认端口没有被其他程序占用 - 跨机器访问时,确认服务端所在网络没有NAT或端口屏蔽限制
内容的提问来源于stack exchange,提问作者deth2macbeth
相关产品推荐
相关产品推荐

