【问题标题】:Does Accept event happens after the three way handshake?三方握手后是否会发生 Accept 事件?
【发布时间】:2013-08-29 09:01:04
【问题描述】:

我正在使用套接字编程在 Linux(客户端和服务器)上编写应用程序。我遇到了这样的场景,我的服务器应用程序从不响应另一端的初始 SYN 数据包。

我仍在调试问题。

由于我的服务器正在侦听端口,它永远不会生成接受事件。是在TCP握手完成后产生accept事件还是在收到初始SYN包时产生accept事件?

一些有用的链接,会很有帮助的。

最好的

【问题讨论】:

  • 也许您的收听积压已满?
  • 您看到的具体行为是什么?您对该行为有何疑问?
  • @xaxxon .. 我没有发现任何接受事件生成,即使 tcpdump 显示 SYN 数据包已到达该特定端口上的服务器。我的问题是:是否未生成接受事件,因为握手不是结束了?

标签: sockets networking tcp client-server


【解决方案1】:

Accept() 不完全是一个事件,而是一个封装了 TCP 握手的服务器端逻辑的函数。该函数被预先调用(等待客户端连接)并在握手结束后返回(它收到来自客户端的 ACK)。

这里有一些详细的解释: http://lwn.net/Articles/508865/ http://www.ibm.com/developerworks/aix/library/au-tcpsystemcalls/

你得到什么样的错误?确保客户端可以访问您的服务器。

【讨论】:

  • 如果您使用 select() 并传递服务器的 fd,那么 accept() 将作为读取事件触发。
  • Manoj,这是否意味着 select() 完成了三次握手,因此客户端认为它已连接,而实际上它应该等待来自服务器的显式“接受”?换句话说,这不会让“接受”变得多余吗?
  • @ManojPandey 是正确的。你的评论没有意义。 accept() 和 select() 都没有“完成握手”。 TCP 在内核中做到了这一点。您的回答没有传达这一点,也没有传达在调用 accept() 之前握手已经发生的可能性。
  • 服务器在队列中维护一个已建立连接的列表,当应用程序调用accept()时,底层将连接出队并将该文件描述符返回给应用程序。因此,当 accept() 调用返回一个 fd 时,已经为该 fd 完成了 3 次握手。
  • 谢谢大家..这澄清了我的疑问。
【解决方案2】:

TCP握手完成后是否产生accept事件

是的。

或者接收到初始SYN包时产生accept事件?

没有。握手已经发生了。 accept() 只是从已接受的连接队列中为您提供一个套接字。当队列为空时,它会阻塞。

这意味着即使服务器从未调用过accept(),客户端也可以连接。

【讨论】:

  • @Zephyr 垃圾。你的引文没有说任何这样的事情。再读一遍。
【解决方案3】:

TCP 握手由内核处理;不涉及服务器进程。内核维护两个队列,一个用于不完整的连接(接收到初始 SYN),一个用于完成连接(3 次握手完成)。

accept 调用检索完整队列中的第一个条目,如果队列为空并且套接字阻塞调用阻塞直到建立连接。如果套接字是非阻塞的,则调用失败并显示EAGAINEWOULDBLOCK

参考:

  1. https://books.google.com/books?id=ptSC4LpwGA0C&lpg=PP1&pg=PA104#v=onepage&q&f=false/0131411551_ch04lev1sec5.html
  2. https://man7.org/linux/man-pages/man2/accept.2.html

【讨论】:

    猜你喜欢
    • 2017-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 2017-07-08
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    相关资源
    最近更新 更多