UDP/TCP Socket通信问题:客户端断连检测及无连接状态判断需求
UDP版本问题修复
1. 客户端“no buffer space is available”错误解决
客户端无限循环调用sendto且无延迟,会瞬间占满系统发送缓冲区导致报错。添加发送间隔并处理断网异常即可修复:
import socket import time def Main(): host = '192.168.100.144' # 客户端IP port = 4005 server = ('192.168.100.113', 4000) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind((host, port)) s.settimeout(5) # 设置超时,避免断网后阻塞 message = "cell" try: while message != 'q': s.sendto(message.encode('utf-8'), server) time.sleep(0.1) # 添加发送间隔,防止缓冲区溢出 except (socket.error, OSError) as e: print(f"发送失败: {e}") finally: s.close() if __name__ == '__main__': Main()
2. 服务器检测客户端断开逻辑
UDP是无连接协议,无法直接感知客户端断开,需通过心跳超时判断:若指定时间内未收到客户端消息,判定为断开并终止循环:
import socket def Main(): host = '192.168.100.113' # 服务器IP port = 4000 timeout = 10 # 10秒未收到消息则判定客户端断开 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind((host, port)) s.settimeout(timeout) print("服务器已启动") try: while True: data, addr = s.recvfrom(1024) data = data.decode('utf-8') if data != 'cell': break print(f"来自客户端 {addr}: {data}") s.sendto("已收到消息".encode('utf-8'), addr) # 收到消息后返回响应 except socket.timeout: print("客户端已断开连接,终止服务") finally: s.close() if __name__ == '__main__': Main()
TCP版本扩展:检测客户端连接状态
TCP是有连接协议,可通过接收数据时的异常判断客户端断开,同时维护活跃连接计数,实现“无客户端连接时终止服务器”的逻辑:
扩展后TCP服务端代码
import socket import threading def handle_client(conn, addr): print(f"新连接: {addr}") try: conn.send("已连接到服务器".encode('utf-8')) # 发送欢迎消息 while True: data = conn.recv(1024) if not data: # 客户端主动关闭连接 break print(f"来自 {addr}: {data.decode('utf-8')}") conn.send(f"已收到: {data.decode('utf-8')}".encode('utf-8')) # 返回响应 except (ConnectionResetError, BrokenPipeError): print(f"客户端 {addr} 异常断开") finally: conn.close() print(f"连接 {addr} 已关闭") # 检查是否还有活跃客户端 global active_connections active_connections -= 1 if active_connections == 0: print("无活跃客户端,终止服务器") global sock sock.close() active_connections = 0 def Main(): global sock, active_connections host = socket.gethostbyname(socket.gethostname()) port = 5050 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((host, port)) sock.listen() print(f"服务器已启动,监听 {host}:{port}") try: while True: try: conn, addr = sock.accept() active_connections += 1 # 启动线程处理客户端,支持多客户端连接 threading.Thread(target=handle_client, args=(conn, addr), daemon=True).start() except OSError: # 监听socket被关闭,退出循环 break finally: sock.close() if __name__ == '__main__': Main()
配套TCP客户端代码
import socket import time def Main(): server_ip = '192.168.100.113' # 替换为服务器实际IP port = 5050 client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: client.connect((server_ip, port)) print("已连接到服务器") message = "cell" while message != 'q': client.send(message.encode('utf-8')) response = client.recv(1024) print(f"服务器响应: {response.decode('utf-8')}") time.sleep(1) except (socket.error, OSError) as e: print(f"连接出错: {e}") finally: client.close() if __name__ == '__main__': Main()
内容的提问来源于stack exchange,提问作者Diana
相关产品推荐
相关产品推荐

