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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 01:14:55