C语言 TCP:当客户端在接受之前连接、发送数据和断开连接时会发生什么情况



我正在用 C 语言测试一些代码,我发现 TCP 套接字调用的行为很奇怪。

  1. 我定义了一个同步接受客户端的侦听线程,在接受客户端后,它会在 for 循环中处理它,直到断开连接。因此,一次只处理一个客户端。所以我在循环中调用accept,然后在内部循环中recv,直到收到空缓冲区。

  2. 用客户端触发 5 个线程,我调用connectsend,最后close

  3. 我在任何通话中都没有收到错误。一切似乎都很好。

但是,当我在服务器端打印收到的消息时,结果发现只有第一个客户端进入服务器,即accept永远不会在其他客户端上开火。

所以我的问题是:

  1. connect不应该等到服务器调用accept吗?还是内核层在后台负责缓冲?
  2. 如果不是这种情况,那么服务器是否应该无论如何都能够接受套接字,即使它处于断开连接状态?我的意思是预计它会丢失所有传入的数据吗?
  3. 还是我应该假设我的代码中存在错误?

TCP 状态机与客户端的状态机执行同步舞蹈。所有这些都是在操作系统级别(TCP/IP堆栈)执行的;用户空间进程只能不时地执行一些系统调用来影响此机器。一旦客户端调用listen()此机器就会启动;并将建立新的联系。

还记得listen(int fd, int backlog)的第二个参数吗?整个 3way 握手(通过 TCP 堆栈)完成,然后accept()将 fd 传送到用户空间中的服务器。所以:套接字处于连接状态,但用户进程尚未拾取它们(通过调用accept())

调用accept()将导致内核对新连接进行排队。这些连接功能齐全,但显然数据缓冲区可能会填满,连接会受到限制。

推荐阅读:Comer& Stevens:使用TCP/IP 10.6-10.7的Internetworking(包含TCP状态图)

最新更新