windows - 有没有办法缩短 connect_ex() 的超时时间?

标签 windows python-2.7 sockets

我正在尝试解决网络连接问题,试图了解为什么有些用户可以在开机时看到一个盒子,而其他用户可能需要近 20 秒才能看到它。它在我们的本地程序中造成了一些致命的问题。

为此,我运行了一个简单的最小可验证 python 脚本来尝试找出发生了什么:

import socket
import time
import errno

HOST = '192.168.1.1'
PORT = 12345

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(1)

while(True):
   err = s.connect_ex((HOST, PORT))
   if err == 0:
      print("CONNECTED")
   else:
      print("NO CONNECTION: {0}".format(errno.errorcode[err]))
   time.sleep(2)

当我运行此代码时,我看到一个一致的模式:EAGAIN,后跟 10 个 EALREADY 实例。当它确实连接时,“CONNECTED”将替换周期的 EAGAIN 位。

我认为将超时设置为 1 秒,然后等待 2 秒,应该可以让我更快地中止后台的连接调用,但它似乎没有任何效果。是否有我可以设置的 TCP 选项,或者我可以调整的 Windows 设置,以确保在轮询远程设备连接情况时不会出现这些尴尬的 20 秒阻塞?

最佳答案

通过在套接字上设置超时,socket.connect_ex() 成为非阻塞操作。这就是为什么在循环中重复调用 connect_ex() 时会出现 EAGAINEALREADY 错误 - EAGAIN on第一个调用指示连接无法立即完成,并且正在后台进行中,然后后续调用中的 EALREADY 指示现有连接仍在进行中且尚未完成。

您的循环只是运行,直到连接最终以成功或失败结束,无论需要多长时间。您设置的套接字超时不符合该逻辑。

要执行您要求的操作,请与连接循环并行运行您自己的计时器,然后如果在 socket.connect_ex() 返回最终结果之前计时器已过,则关闭套接字。

或者,完全摆脱循环。

调用一次socket.connect_ex(),如果返回EAGAIN,则使用select.select()等待连接完成。它有一个超时参数。如果挂起的连接尝试成功连接到服务器,TCP 套接字将进入可写状态。如果 select() 超时或报告错误,请关闭套接字。

或者,尝试使用 socket.create_connection(),它也有一个 timeout 参数。

关于windows - 有没有办法缩短 connect_ex() 的超时时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56760686/

相关文章:

windows - 为什么此批处理脚本中的FOR/f循环求空行?

windows - WCF 作为服务托管

c++ - 调用 accept() 时出现异常

python-2.7 - python版本之间不同的base64编码

python - 使用正则表达式从文件中获取测试详细信息

Python 2.7 参数解析 : How to nest optional mutally exclusive arguments properly?

php - Socket php 服务器不显示从 android 客户端发送的消息

android - 如何在 Windows 中创建新的构建工具 sdk

c - 如何将 getaddrinfo 中的 IPv6 地址存储到字符数组中?

sockets - UDP有多安全?