我正在实现一个简单的服务器,它接受单个连接,然后使用该套接字同时从读写线程读取和写入消息。在 Linux 上的 c/c++ 中同时读取和写入同一个套接字描述符的安全且简单的方法是什么?我不需要担心从同一个套接字读取和写入的多个线程,因为将有一个专用的读取和一个专用的写入线程写入套接字。
在上述情况下,是否需要任何类型的锁定?
上述场景是否需要非阻塞套接字?
是否有任何开源库可以在上述情况下有所帮助?
原文由 Jimm 发布,翻译遵循 CC BY-SA 4.0 许可协议
我正在实现一个简单的服务器,它接受单个连接,然后使用该套接字同时从读写线程读取和写入消息。在 Linux 上的 c/c++ 中同时读取和写入同一个套接字描述符的安全且简单的方法是什么?我不需要担心从同一个套接字读取和写入的多个线程,因为将有一个专用的读取和一个专用的写入线程写入套接字。
在上述情况下,是否需要任何类型的锁定?
上述场景是否需要非阻塞套接字?
是否有任何开源库可以在上述情况下有所帮助?
原文由 Jimm 发布,翻译遵循 CC BY-SA 4.0 许可协议
你不必担心。一个线程读取和一个线程写入将按您的预期工作。套接字是全双工的,所以你可以边写边读,反之亦然。如果您有多个作家,您将不得不担心,但事实并非如此。
原文由 mfontanini 发布,翻译遵循 CC BY-SA 3.0 许可协议
7 回答5.3k 阅读
3 回答2k 阅读✓ 已解决
4 回答4k 阅读
2 回答3.9k 阅读✓ 已解决
2 回答5.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
没有任何。
您可能担心的位 -
read
/recv
和write
/send
已建立的线程 -2 不需要 如果您对这些线程坐在那里等待完成感到高兴,那就是非阻塞的。这通常是您使用线程而不是select
、epoll
、 异步操作 或 io_uring 的原因之一 - 也使代码更简单。如果接受新客户端的线程很乐意阻止对
accept()
的调用,那么你也很好。不过,您可能希望记住 TCP 服务器的一个微妙问题……如果您的程序增长到可以处理多个客户端并需要定期进行一些内务处理。使用
select
或epoll
调用以检查侦听套接字上的可读性是很自然和诱人的 - 这表明客户端连接尝试 - 然后是accept
连接。那里有一个竞争条件:客户端连接尝试可能已经在select()
和accept()
之间下降,在这种情况下accept()
将阻塞如果监听套接字不是 非阻塞 的,这可以防止及时返回到select()
循环并暂停周期性的超时处理,直到另一个客户端连接。有数百个用于编写基本服务器的库(并且要求 3rd 方库建议在 SO 上是题外话,所以我不会进入它),但最终你所要求的很容易在操作系统提供的 BSD 上实现 套接字 API 或 Windows 混蛋( “winsock” )。