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

如何实现可中断的持久Socket连接?解决消息发送异常

持久化Socket连接实现方案

你的问题根源在服务端逻辑:当前服务端每接受一个客户端连接后,仅调用一次recv()就回到accept()等待新连接,导致客户端后续发送的消息无法被监听。要实现单连接下的持续通信,服务端需在建立连接后,循环接收该客户端的消息,直到连接断开或触发中断。

修改后的服务端代码

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 8888))
s.listen(5)
print("服务端启动,等待客户端连接...")

try:
    while True:
        client, addr = s.accept()
        print(f"客户端 {addr} 已连接")
        # 持续接收当前客户端的消息
        while True:
            try:
                res = client.recv(1024)
                if not res:  # 客户端主动断开时,recv返回空字节
                    print(f"客户端 {addr} 已断开")
                    client.close()
                    break
                print(addr, 'says:', res.decode('utf-8'))
            except KeyboardInterrupt:
                print("\n收到中断信号,关闭所有连接")
                client.close()
                s.close()
                exit()
except KeyboardInterrupt:
    print("\n服务端已关闭")
    s.close()

修改后的客户端代码

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('127.0.0.1', 8888))
print("已连接到服务端,输入'exit'断开连接,按Ctrl+C中断")

try:
    while True:    
        com = input('Enter the message: ')
        if com == 'exit':
            s.send(com.encode())
            print('发送退出指令,断开连接')
            s.close()
            break
        s.send(com.encode())   
        print('消息已发送')
except KeyboardInterrupt:
    print("\n收到中断信号,关闭连接")
    s.close()

核心改进点

  • 服务端新增内层循环,在接受客户端连接后持续调用recv(),直到客户端断开或触发中断,确保能接收所有后续消息。
  • 客户端保持单次Socket初始化与连接,避免频繁创建连接的开销,同时添加KeyboardInterrupt捕获逻辑,保证中断时能正确关闭Socket。
  • 处理了客户端主动断开的场景(recv()返回空字节),避免服务端阻塞。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:20:23