连接()阻塞的TCP套接字?

您好我正在阅读TLPI(Linux编程接口),我有一个关于connect()的问题。

据我所知,如果listen()的未决连接数没有达到“backlog”,connect()将立即返回。 否则会阻塞。 (根据图56-2)

但对于TCP套接字,它将一直阻塞,直到服务器端的accept()被调用(如图61-5所示)。

我对么? 因为我在示例代码(p.1265)中看到,它调用listen()来侦听特定的端口,然后在调用accept()之前调用connect()到那个端口。

所以在这种情况下connect()会永远封锁,不是吗?

谢谢!!

Solutions Collecting From Web of "连接()阻塞的TCP套接字?"

关于网络几乎没有什么“立即”的东西可以在途中丢失,理论上应立即执行的操作在实践中可能不会这样做,并且在任何情况下都有端到端的传输时间。

然而

  • 除非套接字描述符被置于非阻塞模式,否则TCP套接字上的connect()是一个阻塞操作。

  • 操作系统负责TCP握手,当握手完成时,connect()返回。 (也就是说connect()不会阻塞,直到另一端调用accept())

  • 一个成功的TCP握手将排队等待服务器应用程序,并且可以在稍后的任何时候接受()。

connect默认是一个阻塞调用,但是你可以通过传递socket SOCK_NONBLOCK标志来阻塞它。

connect()阻塞,直到完成TCP 3次握手。 监听端的握手由内核中的TCP / IP协议栈处理,并在不通知用户进程的情况下完成。 只有握手完成后(发起者可以从connect()调用已经返回),accept()在用户进程中可以拿起新的socket并返回。 无需等待接受()完成握手。

原因很简单:如果您有单线程进程监听连接,并且需要等待accept()来建立连接,则在处理另一个请求时,不能对TCP SYN进行响应。 初始端的TCP堆栈将重新传输,但是在适度加载的服务器上机率很高,这个重新传输的数据包仍然会到达,而没有accept()挂起,并会再次丢弃,导致丑陋的延迟和连接超时。