c - TCP:客户端连接,发送数据并在接受之前断开连接时会发生什么

标签 c sockets 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) 的第二个参数吗?在 accept() 将 fd 传递到用户空间的服务器之前,整个 3way 握手完成(由 TCP 堆栈)。所以:套接字处于连接状态,但用户进程尚未拾取它们(通过调用 accept() )

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

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

关于c - TCP:客户端连接,发送数据并在接受之前断开连接时会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43328803/

相关文章:

c - 单词交换。 swaw 是否已弃用

java - 我使用 Sockets 和 Netty 时遇到 "broken pipe"异常。怎么了?

c - 在 TCP/IP echo 服务器中的三个远程终端上打印

C printf 函数无法正确对齐包含土耳其字符的字符串

c - 需要移动motion.c中的更新值并改变方向

c - 已经启动了多少个控制台应用程序副本

c# - C# 中内存占用最少的最快的序列化器和反序列化器?

.net - .net使用ReceiveAsync检测断开连接

java - Golang TCP 客户端不向 Java TCP 服务器发送 `End of Stream`

Java套接字多次写入和读取