网络编程noob,
我对accept
和connect
套接字函数的行为感到困惑。在大多数编程语言中,这些函数的包装器返回不同类型的值:accept
返回我们可用于发送/接收数据的新描述符,但connect
不返回任何值(或返回错误代码)。
对我而言,connect
看起来也应该返回一个描述符。它们都在两个套接字之间打开一个通道,但只有一个函数返回一些与远程套接字通信有用的东西。
这会影响我构建程序的方式。例如,我可以轻松地生成一个新的worker / thread / etc.对于每个传入的连接,但我使用connect
创建的每个连接都不容易实现,因为在这种情况下我没有新的描述符。(所以我不能这样做使用recv
和send
而不做一些记账)
任何人都可以解释一下,为什么这样做?
我认为原因是因为编程语言中的socket
包装器紧跟BSD API,在这种情况下我的问题是:为什么BSD套接字以这种方式工作?当前的实现导致不必要的复杂程序或冗余套接字。我要么需要做更多的预订(导致更复杂的程序),要么为每个外出连接创建一个新的套接字(导致冗余套接字)。
感谢。
答案 0 :(得分:2)
connect()
将现有描述符作为输入。首先创建和配置描述符,然后connect()
到服务器。所以没有必要返回一个新的描述符,因为你必须事先创建描述符。
accept()
也将现有描述符作为输入,但该描述符表示侦听套接字。当接受客户端时,需要一个唯一的描述符来读取/写入该特定客户端,监听描述符不能用于此,因此accept()
返回一个新的描述符。
您不需要以不同方式构建线程。在客户端,在connect()
到服务器之后,生成一个线程并为其提供已连接的描述符。在服务器端,在accept()
客户端之后,生成一个线程并为其提供已接受的描述符。在这两种情况下,线程只需关心要操作的描述符,而不是该描述符的来源。两个线程都可以根据需要使用recv()
和send()
,然后在使用它时使用close()
描述符。
您无法为新连接重用套接字描述符(Windows上的WinSock2具有允许的非标准扩展,但该功能并不常用)。断开连接后,必须关闭其描述符。您需要在需要创建新连接时创建新描述符。