首页 > 解决方案 > 给定一个从客户端到服务器的已建立 tcp 连接,是否在没有服务器显式调用接受的情况下解决了第二个连接?

问题描述

如果我的术语非常初级,请提前道歉:

我正在使用与服务器建立 tcp 连接的客户端。客户端的套接字是非阻塞的,所以在调用之后connect(),客户端等待套接字变为可写。

在从客户端获取连接后,服务器执行阻塞操作(称为函数 X)并且很长时间accept()不会返回阻塞状态。accept()

在服务器被占用执行功能 X 期间,客户端connect()对同一服务器执行另一个操作,再次使用非阻塞套接字(与第一个连接使用的套接字不同),然后等待套接字变为可写以考虑tcp 连接为“已建立”。

accept()我天真地期望第二个套接字在服务器第二次调用以接受第二个连接之前保持不可写。但我观察到情况并非如此:第二个套接字很快变得可写,因此客户端再次将这个新的 tcp 连接视为“已建立”。

这是预期的吗?

这个问题的一个评论中,我(非常松散地)了解到,在 tcp 连接中间的非阻塞套接字在执行 TCP 握手期间将保持不可写 - 这是真的吗?这与上述问题有关吗?是否类似于:如果存在从客户端到服务器的现有 tcp 连接,则从同一客户端到同一服务器的后续 tcp 连接将立即/快速“解析”(套接字变为可写而服务器无需显式执行第二次accept)?

我尝试了什么

我尝试编写一个单元测试来模拟这种情况,每个线程用于在单个 PC 上运行的客户端和服务器,但我认为这不是一种有效的测试方法:根据这个 Q&A,我认为客户端和服务器是否在同一个PC,“TCP握手”与两台单独的PC不太一样,例如,客户端的连接套接字在服务器甚至没有监听的情况下变得可写,更不用说接受连接了。

标签: linuxsocketstcp

解决方案


每个都connect()需要一个对应accept()的,以便客户端和服务器相互通信。

但是,有可能/很可能在连接仍在服务器的积压中时完成 3 次 TCP 握手,然后accept()为其创建新套接字。一旦握手完成,连接就“建立”了,这将完成connect()客户端的操作,即使连接还没有accept()在服务器端建立。

查看TCP 积压工作在 Linux 中的工作原理


推荐阅读