select()是否可以用于客户端,而不仅仅是服务器?
我想创建一个TCP客户机,当接收数据的select()循环在单独的线程中运行时,它可以建立多个连接。不过,我不确定这是否可行,因为select()循环已经在运行,因此即使线程安全问题得到解决,我也不知道它如何“注意到”添加了一个新套接字 有没有办法做到这一点,或者我必须在每次建立新连接时生成一个新线程并使用recv()select()是否可以用于客户端,而不仅仅是服务器?,c,networking,sockets,network-programming,C,Networking,Sockets,Network Programming,我想创建一个TCP客户机,当接收数据的select()循环在单独的线程中运行时,它可以建立多个连接。不过,我不确定这是否可行,因为select()循环已经在运行,因此即使线程安全问题得到解决,我也不知道它如何“注意到”添加了一个新套接字 有没有办法做到这一点,或者我必须在每次建立新连接时生成一个新线程并使用recv() (为了清晰起见进行了编辑。)当然有可能。函数接受三组文件句柄,一组用于读取,一组用于写入,一组用于错误。只需将套接字添加到读取集中,当服务器向您发送内容时,您就会被注意到 有代码
(为了清晰起见进行了编辑。)当然有可能。
函数接受三组文件句柄,一组用于读取,一组用于写入,一组用于错误。只需将套接字添加到读取集中,当服务器向您发送内容时,您就会被注意到
有代码显示如何执行此操作。在客户端套接字上选择()的另一个好理由是跟踪传出TCP连接的进度。例如,这允许设置连接超时
- 将客户端套接字设置为非阻塞
- 调用connect()。它可能会返回EINPROGRESS错误集(连接正在进行,您不会被阻止,因为套接字是非阻塞的)
- 现在选择()并将FD_设置为“write ready”跟踪客户端套接字。您还可以设置超时
- 分析select()结果
- 分析上次客户端套接字操作是失败还是成功
最有用的是,您可以在不同状态的多个套接字上使用它。因此,您可以对套接字的数量(客户端、服务器、传出、侦听、接受……)进行真正的无阻塞处理。所有这些都只需要一根螺纹。一个简单的方法就是在管道上选择
。在您安排好线程也将选择新连接上的
之后,您将在管道上写入一个字节。这会导致线程从select
中退出。当它注意到管道可读时,它会读取字节以“重置”管道,以便再次使用,更新其文件描述符集,并返回到select
ing。Ok谢谢,因此即使select()在循环中运行,并且从使用connect()的完全不同的线程添加套接字,它仍然会注意到读取集刚刚接收到一个新的加法,并将开始接收其中的数据?这有点违反直觉,但我会试试看,嗯?线程?我以为你在问题中说的是“单线程”。请编辑您的问题,以便更清楚地描述如何使用线程。FD_集(很可能)不是线程安全的,因此如果从多个线程向共享集添加套接字,则需要小心。抱歉,我认为这是明确的,因为select()必须在循环中运行,因此除非我在进入循环之前建立所有连接,否则我会被迫在单独的线程中建立连接。通过“单线程”我的意思是,我希望在一个线程中接收来自当前所有连接的所有数据,但我仍然需要一个单独的线程来建立这些连接。为了清楚起见,我对问题进行了编辑。如果在非阻塞套接字上调用connect()
,则调用会立即返回,并且在建立连接时,select()
会将套接字返回为“可写”。因此,您可以在“接收”线程中打开连接。