为什么套接字可以将connect()连接到其自己的临时端口? [英] Why can a socket connect() to its own ephemeral port?
问题描述
如果我使用自动分配的临时端口(5000–65534)范围内的端口连接到localhost,则可以可靠地将Winsock套接字连接至connect()
.具体地说,Windows似乎具有系统范围的滚动端口号,这是它将尝试分配为客户端套接字的本地端口号的下一个端口.如果我在指定的号码刚好低于目标端口号之前创建套接字,然后重复创建套接字并尝试连接到该端口号,通常我就可以使套接字自行连接.
I can reliably get a Winsock socket to connect()
to itself if I connect to localhost with a port in the range of automatically assigned ephemeral ports (5000–65534). Specifically, Windows appears to have a system-wide rolling port number which is the next port that it will try to assign as a local port number for a client socket. If I create sockets until the assigned number is just below my target port number, and then repeatedly create a socket and attempt to connect to that port number, I can usually get the socket to connect to itself.
我首先使它发生在反复尝试连接到本地主机上某个端口的应用程序中,并且当服务未在监听时,它很少成功建立连接并接收其最初发送的消息(是Redis PING
命令).
I first got it to happen in an application that repeatedly tries to connect to a certain port on localhost, and when the service is not listening it very rarely successfully establishes a connection and receives the message that it initially sent (which happens to be a Redis PING
command).
在Python中的示例(运行时不监听目标端口):
An example, in Python (run with nothing listening to the target port):
import socket
TARGET_PORT = 49400
def mksocket():
return socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
while True:
sock = mksocket()
sock.bind(('127.0.0.1', 0))
host, port = sock.getsockname()
if port > TARGET_PORT - 10 and port < TARGET_PORT:
break
print port
while port < TARGET_PORT:
sock = mksocket()
err = None
try:
sock.connect(('127.0.0.1', TARGET_PORT))
except socket.error, e:
err = e
host, port = sock.getsockname()
if err:
print 'Unable to connect to port %d, used local port %d: %s' % (TARGET_PORT, port, err)
else:
print 'Connected to port %d, used local port %d' (TARGET_PORT, port)
在我的Mac机器上,它最终以Unable to connect to port 49400, used local port 49400
终止.在我的Windows 7计算机上,成功建立了连接,并显示Connected to port 49400, used local port 49400
.生成的套接字接收发送给它的所有数据.
On my Mac machine, this eventually terminates with Unable to connect to port 49400, used local port 49400
. On my Windows 7 machine, a connection is successfully established and it prints Connected to port 49400, used local port 49400
. The resulting socket receives any data that is sent to it.
这是Winsock中的错误吗?这是我代码中的错误吗?
Is this a bug in Winsock? Is this a bug in my code?
这是 TcpView的屏幕截图,其中显示有问题的连接:
Here is a screenshot of TcpView with the offending connection shown:
推荐答案
This appears to be a 'simultaneous initiation' as described in #3.4 of RFC 793. See Figure 8. Note that neither side is in state LISTEN at any stage. In your case, both ends are the same: that would cause it to work exactly as described in the RFC.
这篇关于为什么套接字可以将connect()连接到其自己的临时端口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!