套接字编程 - listen()和accept()之间有什么区别?

Zen*_*ker 17 c sockets network-programming tcp

我一直在阅读本教程以了解套接字编程.似乎listen()accept()系统调用都做同样的事情,即阻塞并等待客户端连接到使用socket()系统调用创建的套接字.为什么你需要两个单独的步骤呢?为什么不只使用一个系统调用?

顺便说一句,我搜索了这个问题,发现了类似的问题,但没有一个答案令人满意.例如,其中一个人说accept()创建套接字是没有意义的,因为我知道套接字是由创建的socket().

Ser*_*eyA 20

这是历史建筑的一部分.listen为下次accept通话准备套接字.Listen还允许人们设置积压 - 系统将接受的连接数,而不是让你的程序真正接受它们.积压完成之后的所有内容都会被系统立即拒绝.listen永远不会阻塞,同时accept阻塞(除非套接字处于非阻塞模式),直到下一个连接出现.显然,这不一定是两个独立的功能 - 可以想象accept()功能可以做到一切listen.


Som*_*ude 18

listen()函数基本上在内部套接字结构中设置一个标志,将套接字标记为被动侦听套接字,您可以调用该套接字accept.它打开绑定端口,以便套接字可以开始接收来自客户端的连接.

accept()函数要求侦听套接字接受下一个传入连接并返回该连接的套接字描述符.因此,从某种意义上说, accept() 确实创建了一个套接字,而不是listen()用于传入连接的套接字.


J A*_*ish 9

以上两个答案清楚地说明了接受和倾听之间的区别。回答你的另一个问题——为什么我们需要两个独立的功能?

一个用例是,例如,如果您只想测试一个端口是否仍然可用/和可访问,您可以通过监听端口然后关闭它而不接受任何连接来实现。

例如https://github.com/coolaj86/golang-test-port使用监听调用来测试端口的可用性。