我一直在阅读this tutorial以了解套接字编程。似乎listen()
和accept()
系统调用都执行相同的操作,即阻塞并等待客户端连接到使用socket()
系统调用创建的套接字。为什么你需要两个单独的步骤呢?为什么不只使用一个系统调用?
顺便说一下,我搜索了这个问题,发现了类似的问题,但没有一个答案令人满意。例如,其中一个人说accept()
创建套接字,这是没有意义的,因为我知道套接字是由socket()
创建的。
答案 0 :(得分:19)
这是历史性设置的一部分。 accept
为下一次listen
电话准备套接字。 Listen还允许人们设置积压 - 系统将接受的连接数,而不是让你的程序真正接受它们。积压完成之后的所有内容都会被系统立即拒绝。 accept
永远不会阻塞,而accept()
将阻塞(除非套接字处于非阻塞模式),直到下一个连接出现。显然,这不一定是两个单独的函数 - 可以想象listen
函数可以完成-fopenmp
所做的一切。
答案 1 :(得分:17)
listen()
函数基本上在内部套接字结构中设置一个标志,将套接字标记为被动侦听套接字,可以调用accept
。它打开绑定端口,以便套接字可以开始接收来自客户端的连接。
accept()
函数要求侦听套接字接受下一个传入连接并返回该连接的套接字描述符。因此,从某种意义上说,accept()
会创建一个套接字,而不是您用于listen()
传入连接的套接字。
答案 2 :(得分:3)
以上两个答案清楚地说明了接受和倾听之间的区别。回答你的另一个问题 - 为什么我们需要两个独立的功能?
一个用例是,例如如果您只想测试一个端口是否仍然可用/可访问,您只需要监听端口然后关闭它而不接受任何连接即可。
例如https://github.com/coolaj86/golang-test-port使用listen调用来测试端口的可用性。