select()是否可以用于客户端,而不仅仅是服务器?

select()是否可以用于客户端,而不仅仅是服务器?,c,networking,sockets,network-programming,C,Networking,Sockets,Network Programming,我想创建一个TCP客户机,当接收数据的select()循环在单独的线程中运行时,它可以建立多个连接。不过,我不确定这是否可行,因为select()循环已经在运行,因此即使线程安全问题得到解决,我也不知道它如何“注意到”添加了一个新套接字 有没有办法做到这一点,或者我必须在每次建立新连接时生成一个新线程并使用recv() (为了清晰起见进行了编辑。)当然有可能。函数接受三组文件句柄,一组用于读取,一组用于写入,一组用于错误。只需将套接字添加到读取集中,当服务器向您发送内容时,您就会被注意到 有代码

我想创建一个TCP客户机,当接收数据的select()循环在单独的线程中运行时,它可以建立多个连接。不过,我不确定这是否可行,因为select()循环已经在运行,因此即使线程安全问题得到解决,我也不知道它如何“注意到”添加了一个新套接字

有没有办法做到这一点,或者我必须在每次建立新连接时生成一个新线程并使用recv()


(为了清晰起见进行了编辑。)

当然有可能。
函数接受三组文件句柄,一组用于读取,一组用于写入,一组用于错误。只需将套接字添加到读取集中,当服务器向您发送内容时,您就会被注意到


有代码显示如何执行此操作。

在客户端套接字上选择()的另一个好理由是跟踪传出TCP连接的进度。例如,这允许设置连接超时

  • 将客户端套接字设置为非阻塞
  • 调用connect()。它可能会返回EINPROGRESS错误集(连接正在进行,您不会被阻止,因为套接字是非阻塞的)
  • 现在选择()并将FD_设置为“write ready”跟踪客户端套接字。您还可以设置超时
  • 分析select()结果
  • 分析上次客户端套接字操作是失败还是成功

最有用的是,您可以在不同状态的多个套接字上使用它。因此,您可以对套接字的数量(客户端、服务器、传出、侦听、接受……)进行真正的无阻塞处理。所有这些都只需要一根螺纹。

一个简单的方法就是在管道上选择
。在您安排好线程也将
选择新连接上的
之后,您将在管道上写入一个字节。这会导致线程从
select
中退出。当它注意到管道可读时,它会读取字节以“重置”管道,以便再次使用,更新其文件描述符集,并返回到
select
ing。

Ok谢谢,因此即使select()在循环中运行,并且从使用connect()的完全不同的线程添加套接字,它仍然会注意到读取集刚刚接收到一个新的加法,并将开始接收其中的数据?这有点违反直觉,但我会试试看,嗯?线程?我以为你在问题中说的是“单线程”。请编辑您的问题,以便更清楚地描述如何使用线程。FD_集(很可能)不是线程安全的,因此如果从多个线程向共享集添加套接字,则需要小心。抱歉,我认为这是明确的,因为select()必须在循环中运行,因此除非我在进入循环之前建立所有连接,否则我会被迫在单独的线程中建立连接。通过“单线程”我的意思是,我希望在一个线程中接收来自当前所有连接的所有数据,但我仍然需要一个单独的线程来建立这些连接。为了清楚起见,我对问题进行了编辑。如果在非阻塞套接字上调用
connect()
,则调用会立即返回,并且在建立连接时,
select()
会将套接字返回为“可写”。因此,您可以在“接收”线程中打开连接。