socket API:为什么`connect`没有返回描述符?

时间:2014-11-16 14:56:11

标签: sockets network-programming

网络编程noob,

我对acceptconnect套接字函数的行为感到困惑。在大多数编程语言中,这些函数的包装器返回不同类型的值:accept返回我们可用于发送/接收数据的新描述符,但connect不返回任何值(或返回错误代码)。

对我而言,connect看起来也应该返回一个描述符。它们都在两个套接字之间打开一个通道,但只有一个函数返回一些与远程套接字通信有用的东西。

这会影响我构建程序的方式。例如,我可以轻松地生成一个新的worker / thread / etc.对于每个传入的连接,但我使用connect创建的每个连接都不容易实现,因为在这种情况下我没有新的描述符。(所以我不能这样做使用recvsend而不做一些记账)

任何人都可以解释一下,为什么这样做?

我认为原因是因为编程语言中的socket包装器紧跟BSD API,在这种情况下我的问题是:为什么BSD套接字以这种方式工作?当前的实现导致不必要的复杂程序或冗余套接字。我要么需要做更多的预订(导致更复杂的程序),要么为每个外出连接创建一个新的套接字(导致冗余套接字)。

感谢。

1 个答案:

答案 0 :(得分:2)

connect()将现有描述符作为输入。首先创建和配置描述符,然后connect()到服务器。所以没有必要返回一个新的描述符,因为你必须事先创建描述符。

accept()也将现有描述符作为输入,但该描述符表示侦听套接字。当接受客户端时,需要一个唯一的描述符来读取/写入该特定客户端,监听描述符不能用于此,因此accept()返回一个新的描述符。

您不需要以不同方式构建线程。在客户端,在connect()到服务器之后,生成一个线程并为其提供已连接的描述符。在服务器端,在accept()客户端之后,生成一个线程并为其提供已接受的描述符。在这两种情况下,线程只需关心要操作的描述符,而不是该描述符的来源。两个线程都可以根据需要使用recv()send(),然后在使用它时使用close()描述符。

您无法为新连接重用套接字描述符(Windows上的WinSock2具有允许的非标准扩展,但该功能并不常用)。断开连接后,必须关闭其描述符。您需要在需要创建新连接时创建新描述符。