我可以为多个连接使用相同的套接字吗?

时间:2018-01-09 00:42:02

标签: python sockets networking

我正在尝试创建一个扫描一系列地址的python函数。我启动了一个套接字并将套接字作为参数传递给连接它的函数:

def scan(socket, address, port):
    c = socket.connect_ex((address, port))
    print(c)

然后我为每个地址调用scan,每个地址都在自己的线程中。我得到了Error 114: Operation already in progress.

我是否需要为每个连接启动一个新套接字?我正在尝试阅读有关套接字重用的内容,我发现存在SO_ADDREUSE之类的标记或类似的东西。我试图插入,但它没有用。

我正在考虑套接字是如何工作的。我想当我创建一个时,它会选择一个tcp源端口,然后当我创建一个连接时,它会发送到目标端口。我想我不能重复使用相同的套接字,因为所有目标端口的源端口都是相同的,所以客户端会回答同一个端口并导致混淆。

那么我需要为每个连接创建一个新套接字吗?

2 个答案:

答案 0 :(得分:0)

  

我正在考虑套接字是如何工作的。我想当我创建一个时,就会选择一个tcp源端口,

在使用socket()系统调用创建套接字并使用它创建具有connect()系统调用的传出连接之间,可以选择使用bind()系统调用如果需要,设置源IP地址和/或端口。如果不使用bind(),则在使用connect()系统调用时,操作系统将自动将套接字绑定到适当范围内的第一个可用端口。在这种情况下,通常选择源IP地址以匹配根据路由表提供到指定目的地的最短路由的网络接口。

至少,这就是它在系统调用级别的工作方式。某些编程语言或库可能会选择将其中一些操作合并为一个。

对于您的实际问题,man 7 ip说:

  

某些已绑定的TCP本地套接字地址不可用    关闭后的时间,除非已设置SO_REUSEADDR标志。关心    使用此标志时应采取这一措施,因为它会降低TCP的可靠性。

我们的想法是延迟重新使用端口,直到任何可能重新发送的属于已关闭连接的软件包副本确实已在网络上过期。

根据bind()手册页,尝试重新绑定已绑定到地址的套接字将导致EINVAL错误。因此,使用bind(socket, INADDR_ANY, 0)(在结束使用SO_REUSEADDR的连接之后)“回收”套接字似乎不可能。

即使这是可能的,当你在现代多核系统上使用多个线程时,你最终(很可能)并行地做多个事情。套接字一次只能用于一个传出连接。每个scan线程都需要自己的套接字。

答案 1 :(得分:0)

  

我是否需要为每个连接启动一个新套接字?

  

我正在尝试阅读有关套接字重用的信息

没有'套接字重用'这样的东西。有端口重用。不一样的事情。一旦尝试连接现有套接字,即使连接尝试失败,也无法重新连接现有套接字。

  

我发现存在像SO_ADDREUSE这样的标志

SO_REUSEADDR表示重用端口。不是插座。