在 TCP 三向握手之前获取 INADDR_ANY 客户端套接字的源 IP 和端口? [英] Obtaining the source IP and port of an INADDR_ANY client socket before the TCP three-way handshake?

查看:37
本文介绍了在 TCP 三向握手之前获取 INADDR_ANY 客户端套接字的源 IP 和端口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是 Windows 7,在 connect 之前使用 bindSO_REUSEADDR,并将本地地址结构设置为 IP 地址 INADDR _ANY 和端口 0(零),以便让操作系统选择客户端套接字的源详细信息.

I'm on Windows 7, using bind before connect with SO_REUSEADDR, and setting the local address structure to IP address INADDR _ANY and port 0 (zero), in order to let the operating system select the source details for a client socket.

首先,我了解到在连接到服务器之前无法获取源 IP,因为此时已选择源 IP,并且多个地址可能有效.但是端口是在连接之前选择的,那么有没有办法弄到呢?(getsockname() 看起来不起作用).

Firstly, I've read that it's not possible to get the source IP before connecting to the server, since it's being chosen at this point and several addresses can be valid. But the port is selected before the connection, so is there a way to get it? (getsockname() looks like to not work).

其次,关于源IP,有没有办法在数据包发送到服务器之前得到它?我需要操作系统选择源 IP 和开始三向握手之间的特定时间.connect() 函数控制了两者.

Secondly, about the source IP, is there a way to get it before a packet is sent to the server? I need the specific time between the moment the OS selected the source IP and the moment it starts the three-way handshake. The connect() function dominates the both.

推荐答案

我使用的是 Windows 7,在 connect 之前使用 bindSO_REUSEADDR

为什么在这种情况下使用 SO_REUSEADDR?你不需要它,它对你的尝试毫无意义.SO_REUSEADDR 通常只用于监听套接字,而不是连接套接字.

Why are you using SO_REUSEADDR in this situation? You don't need it, and it makes no sense for what you are attempting. SO_REUSEADDR should typically only be used for a listening socket, not a connecting socket.

将本地地址结构设置为 IP 地址 INADDR _ANY 和端口 0(零),以便让操作系统选择客户端套接字的源详细信息.

setting the local address structure to IP address INADDR _ANY and port 0 (zero), in order to let the operating system select the source details for a client socket.

bind()一个客户端套接字连接到INADDR_ANY:0是没有意义的.您可以(并且应该)完全省略这样的 bind() 并保持套接字 unbound 直到 connect() 被调用.唯一次你应该永远 bind()客户端套接字是如果你想将它绑定到特定本地 IP 和/或端口.但是在这种情况下你不会这样做,所以摆脱它.

It is meaningless to bind() a client socket to INADDR_ANY:0. You can (and should) omit such a bind() completely and leave the socket unbound until connect() is called. The only time you should ever bind() a client socket is if you want to bind it to a specific local IP and/or Port. But you are not doing that in this situation, so get rid of it.

首先,我了解到在连接到服务器之前无法获取源 IP,因为此时已选择源 IP,并且多个地址可能有效.

Firstly, I've read that it's not possible to get the source IP before connecting to the server, since it's being chosen at this point and several addresses can be valid.

正确,除非您bind()特定源IP.

Correct, unless you bind() to a specific source IP.

但是连接前选择了端口

如果套接字未绑定,或者绑定到源 IP INADDR_ANY 和/或源端口 0,则 connect() 会选择源 IP 和源端口.所以你在 connect() 选择它们之前没有机会查询任何一个值.

Both source IP and source port are selected by connect() if the socket is unbound, or bound to source IP INADDR_ANY and/or source port 0. So you have no opportunity to query either value before connect() has selected them.

有没有办法得到它?(getsockname() 看起来不起作用).

so is there a way to get it? (getsockname() looks like to not work).

getsockname() 正是您所需要的.只要确保在 connect() 首先成功连接到服务器之前,您不会调用它.这在 getsockname() 中有说明 文档:

getsockname() is exactly what you need. Just make sure you are not calling it until connect() has successfully connected to the server first. This is stated in the getsockname() documentation:

这个调用在没有先绑定的情况下进行了连接调用时特别有用;getsockname 函数提供了确定系统已设置的本地关联的唯一方法.
...
当套接字绑定到未指定的地址时,getsockname 函数并不总是返回有关主机地址的信息,除非套接字已通过 connect 或 accept(例如,使用 ADDR_ANY)连接.Windows Sockets 应用程序不得假定地址将被指定除非套接字已连接.用于套接字的地址未知,除非套接字在多宿主主机中使用时已连接.如果套接字使用无连接协议,则在套接字上发生 I/O 之前,地址可能不可用.

This call is especially useful when a connect call has been made without doing a bind first; the getsockname function provides the only way to determine the local association that has been set by the system.
...
The getsockname function does not always return information about the host address when the socket has been bound to an unspecified address, unless the socket has been connected with connect or accept (for example, using ADDR_ANY). A Windows Sockets application must not assume that the address will be specified unless the socket is connected. The address that will be used for the socket is unknown unless the socket is connected when used in a multihomed host. If the socket is using a connectionless protocol, the address may not be available until I/O occurs on the socket.

其次,关于源IP,有没有办法在数据包发送到服务器之前得到它?

Secondly, about the source IP, is there a way to get it before a packet is sent to the server?

对于 TCP,您可以在 connect() 成功连接到服务器后立即使用 getsockname() 检索选定的源 IP.以前没有.

For TCP, you can retrieve the selected source IP using getsockname() immediately after connect() has successfully connected to the server. Not before.

我需要从操作系统选择源 IP 到开始三向握手之间的具体时间.

I need the specific time between the moment the OS selected the source IP and the moment it starts the three-way handshake.

无法确定该细节.任何套接字应用程序都不需要那个细节.为什么需要它?

It is not possible to determine that detail. No socket application should ever need that detail. Why do you need it?

这篇关于在 TCP 三向握手之前获取 INADDR_ANY 客户端套接字的源 IP 和端口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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