如果我的术语非常初级,请提前道歉:
我正在使用一个客户端,该客户端建立与服务器的tcp连接。客户端的套接字是非阻塞的,因此在调用connect()
之后,客户端将等待套接字变为可写的。
当accept()
从客户端连接时,服务器执行阻塞操作(称为函数X),并且在很长一段时间内不会返回到accept()
处的阻塞。
在服务器被占用执行功能X的这段时间内,客户端对同一服务器执行另一个connect()
,再次使用非阻塞套接字(与第一个连接使用的套接字不同),然后等待套接字变为可写,以便将tcp连接视为"已建立">
我天真地期望第二个套接字保持不可写,直到服务器第二次调用accept()
来接受第二个连接。但我观察到情况并非如此:第二个套接字很快变得可写,因此客户端再次认为这个新的tcp连接"已建立">
这是意料之中的事吗
从这个问题的一条评论中,我(非常松散地)理解到,在tcp握手执行期间,位于tcp连接中间的非阻塞套接字将保持不可写状态——这是真的吗?这与上述问题有关吗?是否类似于:如果存在从客户端到服务器的现有tcp连接,那么从同一客户端到同一服务器的后续tcp连接将立即/快速"解析"(套接字变为可写,而服务器不显式执行第二个accept
)?
我尝试了什么:
我试着写一个单元测试来模拟这种情况,客户端和服务器在一台电脑上运行一个线程,但我认为这不是一个有效的测试方法:根据这个问答;A我认为,如果客户端和服务器在同一台电脑上,"TCP握手"与两台独立的电脑不太一样,例如,客户端的连接套接字变得可写,而服务器甚至没有监听,更不用说接受连接了。
每个connect()
都需要一个相应的accept()
,以便客户端和服务器相互通信。
然而,在accept()
为其创建新套接字之前,3路TCP握手可能/很可能在连接仍在服务器的积压工作中时完成。一旦握手完成,连接就"建立"了,这将完成客户端的connect()
操作,即使服务器端的连接还没有accept()
。
请参阅TCP囤积在Linux 中的工作方式