2017-04-10 180 views
1

我测试一些C代码,我发现用TCP套接字调用奇怪的行为会发生什么。TCP:当客户端连接,发送数据和断开连接之前接受

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

  2. 我火5个线程与客户,我叫connectsend最后close

  3. 我在任何呼叫没有错误。一切似乎都很好。

然而,当我打印接收服务器端的消息事实证明,只有第一个客户端拨通了服务器,即accept永远不会触发其他客户端上。

所以我的问题是:

  1. 不应该connect等到服务器调用accept?或者内核层是否照顾了引擎盖下的缓冲区?
  2. 如果不是的话,那么不应该在服务器能够无论如何接受插座,即使它处于断开状态?我的意思是预计会失去所有传入的数据?
  3. 或者我应该假设我的代码中存在一个错误?
+0

记住'听(INT FD,INT积压)'第二个参数网络互联?在accept()将fd传递给用户空间中的服务器之前,整个3way握手完成(通过TCP堆栈)。所以:套接字处于连接状态,但用户进程还没有选择它(通过调用accept()) – joop

+0

@joop右。我现在明白了。所以数据被缓冲了。我没有看到输出的原因是因为我偶然锁定了服务器。所以,谢谢你回答我的问题1.我已经知道答案2。 – freakish

+0

@joop你可能想写它作为答案,所以我可以接受它。 – freakish

回答

1

TCP状态机执行同步舞蹈与客户端的状态机。所有这些都在OS级执行(TCP/IP 堆栈);用户空间进程只能做一些系统调用来影响这个机器。一旦客户拨打listen()这台机器就开始了;并建立新的连接。

记住listen(int fd, int backlog)第二个参数?在accept()将fd传送到用户区中的服务器之前,整个3way握手完成(通过TCP堆栈)。所以说:插座处于连接状态,但用户进程还没有把它们捡起来,但(通过调用accept()

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

推荐阅读:科默&史蒂文斯:使用TCP/IP 10.6-10.7(包含TCP状态图)