您好我正在阅读TLPI(Linux编程接口),我有一个关于connect()的问题。
据我所知,如果listen()的挂起连接数未达到“backlog”,connect()将立即返回。 否则它会阻止。 (根据图56-2)
但对于TCP套接字,它将一直阻塞,直到调用服务器端的accept()(根据图61-5)。
我说错了吗? 因为我在示例代码(p.1265)中看到它,它调用listen()来侦听特定端口,然后在调用accept()之前调用connect()到该端口。
所以在这种情况下connect()会永远阻塞,不是吗?
谢谢!
答案 0 :(得分:22)
关于网络几乎没有“立即”,在途中可能会丢失东西,理论上应该立即执行的操作在实践中可能不会这样做,并且无论如何都有端到端的传输时间。 / p>
然而
TCP套接字上的connect()是阻塞操作,除非套接字描述符被置于非阻塞模式。
操作系统负责TCP握手,握手完成后,connect()返回。 (那是, connect()不会阻塞,直到另一端调用accept())
成功的TCP握手将排队到服务器应用程序,并且可以在以后随时接受()。
答案 1 :(得分:3)
答案 2 :(得分:3)
connect()阻塞,直到完成TCP 3次握手。侦听端的握手由内核中的TCP / IP堆栈处理,并在不通知用户进程的情况下完成。握手完成后(启动器可以从connect()调用返回),用户进程中的accept()可以获取新的套接字并返回。完成握手不需要等待accept()。
原因很简单:如果您有单线程进程侦听连接并需要等待accept()来建立连接,则在处理另一个请求时无法响应TCP SYN。初始端的TCP堆栈将重新发送,但在中等负载的服务器上,这个重新传输的数据包仍然会到达而没有accept()挂起并且将再次丢弃,导致丑陋的延迟和连接超时。