Python Socket路由通信出现地址占用与BrokenPipeError报错如何解决?
问题分析与解决思路
1. OSError: [Errno 98] Address already in use 错误解决
错误原因
你当前的路由1和路由2的套接字逻辑都做了同一个host+port的bind操作,TCP协议规定同一个网络地址(ip+端口对)同一时间只能被一个进程绑定作为监听端口,路由2先启动占用了端口,路由1再绑定自然会报错。
你同时混淆了TCP服务端和客户端的逻辑:
- 被动等待连接的节点(路由2)才需要执行
bind→listen→accept逻辑 - 主动发起连接的节点(路由1)不需要绑定端口,直接调用
connect连接对端的监听地址即可
修复方案
- 如果是测试路由1向路由2发数据的单向场景,直接修改路由1的套接字创建逻辑:
def create_socket(host, port): soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 客户端直接连接服务端,不需要bind和listen soc.connect((host, port)) return soc
- 如果后续要实现6个节点双向互发,需要给每个节点分配唯一的监听端口,比如路由1监听5001、路由2监听5002,以此类推,每个节点各自绑定自己的专属端口,需要向其他节点发数据时,再创建新的客户端套接字连接目标节点的监听端口即可。
- 临时测试可以在所有
bind操作前加端口复用配置,避免进程退出后端口未及时释放的问题:
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 新增端口复用配置 soc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) soc.bind((host, port))
2. BrokenPipeError: [Errno 32] Broken pipe 错误解决
错误原因
- 第一个地址占用的问题未修复时,路由1的套接字本身就没有建立有效连接,调用
send自然会报错 - 路由2的接收逻辑存在关键错误:
accept方法返回的connection对象才是和对端绑定的通信套接字,你直接用监听用的soc调用recv,会直接抛出异常导致路由2进程退出,对端发送数据时就会触发断管错误 - 你之前的代码还存在拼写错误:
soc.rev(1024)正确写法是recv,该错误也会直接导致路由2进程崩溃,连接中断
修复方案
修正路由2的接收逻辑,用accept返回的连接对象做数据收发:
while True: connection, address = soc.accept() print("Accepted a connection from: ", address) # 用返回的connection对象接收数据 data = connection.recv(1024) print(data.decode()) # 数据处理完成后可以选择关闭连接,或者保持长连接处理后续数据 # 如果是长连接场景,需要在内层再加循环持续收当前连接的数据 connection.close()
如果需要节点之间保持长连接持续收发数据,可以修改为如下逻辑:
while True: connection, address = soc.accept() print("Accepted a connection from: ", address) # 内层循环处理当前连接的所有数据 while True: data = connection.recv(1024) if not data: # 对端断开连接,退出内层循环等待新连接 break print(data.decode()) connection.close()
内容的提问来源于stack exchange,提问作者PatTheTrickster
相关产品推荐
相关产品推荐

