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

Python 2简易Socket服务器:recv返回0及errno10035问题排查

解决非阻塞Socket的errno 10035错误 & 理解recv返回0的场景

嘿,我来帮你理清楚这个问题!咱们一步步拆解:

首先,errno 10035对应Windows下的WSAEWOULDBLOCK错误——当你把套接字设为非阻塞模式后,调用recv()时如果当前没有可读取的数据,它不会像阻塞模式那样一直等待,而是直接抛出这个异常,告诉你「现在没数据,稍后再试」。你的代码里没处理这个异常,所以才会触发报错。

修复错误的代码示例

我把你的代码补全并修改了异常处理逻辑,同时修正了原代码里的小问题(比如print语法、未完成的字符串占位):

import socket
import time

def Main():
    host = ""
    port = 80
    indic = 1
    data = ""
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host, port))
    s.listen(1)
    c, addr = s.accept()
    c.setblocking(0)
    print "Connection from: " + str(addr)
    
    while indic:
        try:
            data = c.recv(4096)
            if not data:
                # 这里就是recv返回空串(等效于返回0的逻辑)的场景
                print "Client has closed the connection"
                indic = 0
            else:
                print "From connected user: " + data.strip()
        except socket.error as e:
            # 捕获WSAEWOULDBLOCK错误
            if e.errno == 10035:
                # 暂时没数据,稍作等待后重试
                time.sleep(0.1)
                continue
            else:
                # 处理其他异常,比如连接意外中断
                print "Socket error occurred: ", e
                indic = 0
    c.close()
    s.close()

if __name__ == "__main__":
    Main()

关于recv返回0的场景

recv()返回空字节串(Python 2里是'',Python 3里是b''),只有当客户端主动关闭连接,并且服务器已经接收完该连接上的所有残留数据时才会发生。

举个实际场景:客户端调用socket.close()主动断开套接字,服务器这边的recv()在读完所有剩余数据后,下一次调用就会返回空串——这就是你要的「recv返回0」的判定条件,此时你可以确定客户端已断开,关闭服务器侧的套接字并退出循环即可。

另外补充一个更优雅的非阻塞处理方案:用select模块监听套接字的可读事件,避免频繁sleep和异常捕获,效率更高:

import socket
import select

def Main():
    host = ""
    port = 80
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((host, port))
    s.listen(1)
    c, addr = s.accept()
    c.setblocking(0)
    print "Connection from: " + str(addr)
    
    while True:
        # 监听可读套接字,超时时间设为1秒
        readable, _, _ = select.select([c], [], [], 1)
        if c in readable:
            data = c.recv(4096)
            if not data:
                print "Client disconnected"
                break
            print "From connected user: " + data.strip()
    c.close()
    s.close()

if __name__ == "__main__":
    Main()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:45:33