且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2023-11-22 19:02:46

我正在思考套接字是如何工作的.我想我创建的那一刻,它选择了一个 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.