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

Python Socket双向通信代码挂死问题及回复必要性咨询

Socket双向通信挂死问题解答

双向挂死的根因

  • 服务端阻塞:TCP是字节流协议,不存在一次send对应一次recv的绑定规则。客户端总共发送了6字节数据b"123456",服务端每次调用conn.recv(2)最多读取2字节,循环3次就能读完所有已发送数据。读完后服务端仍会执行下一次conn.recv(2),此时客户端没有新数据发送、也没有关闭连接,阻塞模式的recv会让服务端永久卡在这里等待新数据。
  • 客户端阻塞:客户端发完数据后直接调用cs.recv(1024),阻塞等待服务端返回数据。注释掉回复逻辑时,服务端一直卡在recv步骤,永远不会执行后续的conn.sendall(b"Finished"),两边进入死等状态。

取消注释回复OK后正常运行的原因

开启conn.sendall(b"OK")逻辑后,服务端第一次收到2字节就会给客户端返回OK,客户端的recv收到数据后结束等待,继续执行cs.close()关闭连接。客户端关闭连接后,服务端下一次调用conn.recv(2)会收到空字节,触发if not data: break跳出循环,整个流程正常结束。

服务端即时回复不是强制要求

核心是要明确请求边界,避免两端死等,你可以选择以下任意一种方案替代即时回复:

  • 约定请求长度:比如前4字节存储请求总长度,服务端收满指定长度的数据后,再统一返回响应
  • 约定结束标记:比如请求末尾以\r\n或者自定义特殊字符作为结束符,服务端读到结束符就停止接收请求,再返回响应
  • 客户端发完请求后调用cs.shutdown(socket.SHUT_WR)关闭写端:此时服务端recv会收到空字节,感知到客户端已无数据发送,处理完成后再返回响应即可

代码小瑕疵

服务端接受连接后的打印逻辑有误,print(f"Accepted connection from {HOST}:{PORT}")打印的是服务端自身监听地址,应该修改为打印对端地址:print(f"Accepted connection from {addr[0]}:{addr[1]}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:27:00