python socket 在读取时(recv)服务端断开,这时没有异常,添加超时或非阻塞模式

在Python中使用socket进行通信时,如果客户端断开连接而服务器端在尝试读取时没有捕获到异常,可能会导致recv函数挂起或阻塞。为了捕获这种情况,可以使用超时机制或者非阻塞I/O。

解决方案1:设置超时

import socket
 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)  # 设置超时为5秒
 
try:
    data = s.recv(1024)
except socket.timeout:
    print('The server has disconnected.')

解决方案2:使用非阻塞I/O

import socket
 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setblocking(False)  # 设置为非阻塞模式
 
try:
    data = s.recv(1024)
except BlockingIOError:
    # 这里可以检查客户端是否还活着,如果不活着,那么recv会抛出异常
    # 可以通过尝试发送一个小数据包或者其他方式来检测客户端是否还在线
    pass

在非阻塞模式下,recv调用会立即返回,如果没有数据可读,它将抛出BlockingIOError异常。通过这种方式,你可以检测到客户端断开连接。

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python中的socket.recv()可以设置为阻塞模式,这意味着当没有数据可用,它不会一直等待数据到达。相反,它会立即返回一个错误或一个空字节串。这对于需要同处理多个连接的服务常有用,因为它可以避免一个连接的阻塞影响其他连接的处理。要将socket设置为阻塞模式,可以使用socket.setblocking(False)方法。 ### 回答2: Python中的Socket是一种面向流的网络通信方式,它可以通过"recv()"方法来接收客户发送的数据。而阻塞式的"recv()"方法会一直等待客户发送数据才返回,这可能会造成程序卡死等问题,所以我们可以采用阻塞式来接收数据。 首先,我们需要将socket设置为阻塞模式,即"sock.setblocking(False)"。然后,我们可以调用"recv()"方法。如果没有接收到数据,会抛出"No data available"异常,我们可以通过try-catch语句来避免程序崩溃。如果接收到了数据,"recv()"方法会立即返回。接收到的数据可能不是一个完整的数据包,需要我们自己进行缓存和拼接,直到接收到一个完整的数据包为止。可以通过定义一个缓存区来实现这个功能。 同,我们可以使用"select"模块来监听socket的可读事件,一旦socket可读,我们便可以使用阻塞式的"recv()"方法来接收数据,确保程序不会阻塞。 这样就可以通过阻塞式的方式来接收客户发送的数据,保证了程序的正常运行。 ### 回答3: PythonSocket库提供了处理套接字通信的常用功能。其中,recv()函数是常见的用于接收数据的函数。通常情况下,recv()函数是阻塞的,也就是说如果没有接收到数据,该函数会一直等待,直到数据到来或者超时。 在某些情况下,我们希望recv()函数不会阻塞程序执行,而是在没有接收到数据立即返回。这,我们可以使用阻塞模式来调用recv()函数。 首先,我们需要将套接字设置为阻塞模式,可以通过以下代码实现: ```python import socket # 创建一个套接字,并设置为阻塞模式 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setblocking(False) ``` 接下来,我们可以在调用recv()函数之前,使用try-except语句来捕获异常,从而实现阻塞接收数据: ```python try: data = sock.recv(buffer_size) except socket.error as e: if e.errno == errno.EWOULDBLOCK: # 没有数据可接收 pass else: # 其他错误 print(e) ``` 在这段代码中,我们使用try-except语句来捕获socket.error异常,如果该异常的错误代码为errno.EWOULDBLOCK,则表示当前没有数据可以接收。如果有数据可以接收,则data变量将包含接收到的数据。 需要注意的是,在阻塞模式下,recv()函数可能会接收到部分数据,因此我们需要在循环中多次调用该函数,直到接收到完整的数据。 总之,Python Socket库提供了一种阻塞模式来实现接收数据的方式,给予开发者更多的灵活性和控制力,但也需要对错误码有一定的了解,才能正确地处理异常情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值