我可以为多个连接使用同一个套接字吗? [英] Can I use the same socket for multiple connections?

查看:56
本文介绍了我可以为多个连接使用同一个套接字吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to make a python function that scans a range of addresses. I started a socket and pass the socket as an argument to the function that connects to it:

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

然后我为每个地址调用 scan,每个地址都在它自己的线程中.我收到 错误 114:操作已经在进行中..

then I call scan for each address, each in its own thread. I'm getting Error 114: Operation already in progress..

我需要为每个连接启动一个新的套接字吗?我正在尝试阅读有关套接字重用的信息,我发现存在诸如 SO_ADDREUSE 之类的标志或类似的东西.我尝试插入,但没有成功.

Do I need to start a new socket for each connection? I'm trying to read about socket reusage, and I found that there exists flags like SO_ADDREUSE or something like that. I tried to insert but it didn't work.

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

I'm trying to think how a socket works. I think the moment I create one, it choses a tcp source port, and then when I create a connection, it sends to a destination port. I think I can't reuse the same socket because the source port would be the same for all destination ports, so the clients would answer to the same port and would cause confusion.

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

So do I need to create a new socket for each connection?

推荐答案

我正在思考套接字是如何工作的.我想我创建的那一刻,它选择了一个 tcp 源端口,

I'm trying to think how a socket works. I think the moment I create one, it choses a tcp source port,

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

Between creating a socket using the socket() system call and using it to create an outgoing connection with the connect() system call, there is an opportunity to optionally use the bind() system call to set source IP address and/or port if you want to. If you don't use bind(), the operating system will automatically bind the socket to the first available port in the appropriate range when you use the connect() system call. In this case, the source IP address is normally selected to match the network interface that provides the shortest route to the specified destination according to the routing table.

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

At least, that's how it works at the system call level. Some programming languages or libraries may choose to combine some of these operations into one.

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

To your actual question, man 7 ip says:

已绑定的 TCP 本地套接字地址对某些人不可用关闭后的时间,除非设置了 SO_REUSEADDR 标志.关心使用此标志时应注意,因为它会降低 TCP 的可靠性.

A TCP local socket address that has been bound is unavailable for some time after closing, unless the SO_REUSEADDR flag has been set. Care should be taken when using this flag as it makes TCP less reliable.

这个想法是延迟端口的重用,直到属于关闭连接的任何可能重新发送的包副本在网络上肯定已过期.

The idea is to delay the re-use of a port until any possible re-sent copies of packages that belonged to the closed connection have for sure expired on the network.

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

According to the bind() man page, trying to re-bind a socket that is already bound to an address will result in an EINVAL error. So "recycling" a socket using bind(socket, INADDR_ANY, 0) (after ending a connection that used SO_REUSEADDR) does not seem to be possible.

即使这是可能的,当您在现代多核系统上使用多个线程时,您最终(很可能)会并行执行多项操作.一个套接字一次只能用于一个传出连接.您的每个 scan 线程都需要自己的套接字.

And even if that would be possible, when you're using multiple threads on a modern multi-core system, you end up (very probably) doing multiple things in parallel. A socket can be used for just one outgoing connection at a time. Each of your scan threads will need its own socket.

这篇关于我可以为多个连接使用同一个套接字吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆