考虑TCP的三次握手。可以在此处找到解释。
上面的文章提到,两端可能同时尝试连接,而在这种情况下三次握手仍然有效。
我们能否使用套接字API模拟这种情况呢?通常使用套接字编写的是被动打开(服务器)和主动打开(客户端)吗?
上面的文章提到,两端可能同时尝试连接,而在这种情况下三次握手仍然有效。
我们能否使用套接字API模拟这种情况呢?通常使用套接字编写的是被动打开(服务器)和主动打开(客户端)吗?
使用套接字API可以导致同时进行TCP打开。正如尼古拉所提到的那样,这是执行以下序列并使初始SYN交叉的时间问题。
bind addr1, port1
connect addr2, port2
bind addr2, port2
connect addr1, port1
以下是我如何使用单个Linux主机实现同时打开的步骤:
使用netem减慢环回接口的速度。
tc qdisc add dev lo root handle 1:0 netem delay 5sec
运行两次netcat
netcat -p 3000 127.0.0.1 2000
netcat -p 2000 127.0.0.1 3000
$ lsof -nP -c netcat -a -i # some columns removed
COMMAND PID NAME
netcat 27911 127.0.0.1:2000->127.0.0.1:3000 (ESTABLISHED)
netcat 27912 127.0.0.1:3000->127.0.0.1:2000 (ESTABLISHED)
下面是tcpdump展示给我的内容(为了清晰起见进行了编辑)
127.0.0.1.2000 > 127.0.0.1.3000: Flags [S], seq 1139279069
127.0.0.1.3000 > 127.0.0.1.2000: Flags [S], seq 1170088782
127.0.0.1.3000 > 127.0.0.1.2000: Flags [S.], seq 1170088782, ack 1139279070
127.0.0.1.2000 > 127.0.0.1.3000: Flags [S.], seq 1139279069, ack 1170088783
tc qdisc replace
会出现错误 RTNETLINK: file exists
。此外,我使用了 ls -la /dev/loop0
中的主要和次要编号。 - Rohit Banga为方便参考,除了sigjuice和Nikolai提供的优秀答案,我们可以用Python轻松实现同时打开多个程序。在两个不同的Python解释器中输入以下代码:
>>> import socket
>>> s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s1.bind(('localhost', 1111))
>>> s1.connect(('localhost', 2222))
>>> s1.send('hello')
5
>>> s1.recv(5)
'world'
并且:
>>> import socket
>>> s2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s2.bind(('localhost', 2222))
>>> s2.connect(('localhost', 1111))
>>> s2.recv(5)
'hello'
>>> s2.send('world')
5