Jim*_*imm 36 c c++ sockets linux nonblocking
我正在实现一个简单的服务器,它接受单个连接,然后使用该套接字同时读取和写入来自读写线程的消息.在Linux上的c/c ++中同时读取和写入相同套接字描述符的安全简便方法是什么?我不需要担心从同一个套接字读取和写入多个线程,因为将有一个专用读取和单个专用写入线程写入套接字.
在上面的场景中,是否需要任何类型的锁定?
以上场景是否需要非阻塞套接字?
是否有任何开源库,这将有助于上述情况?
Ton*_*roy 30
在上面的场景中,是否需要任何类型的锁定?
没有.
以上场景是否需要非阻塞套接字?
你可能担心的一点 - 建立连接上的读写线程 - 如果你很高兴那些线程坐在那里等待完成,则不需要非阻塞.这通常是您使用线程而不是选择或轮询或异步操作的原因之一......使代码也更简单.
如果接受新客户的线程很乐意阻止通话accept()
,那么你们也都很好.
尽管如此,您可能希望保留在脑后的TCP服务器存在一个微妙的问题...如果您的程序增长以处理多个客户端并且需要定期管理.使用select
带超时的语句来检查侦听套接字上的可读性(这表示客户端连接尝试)然后accept
是连接是很自然和诱人的.那里有一个竞争条件:客户端连接尝试可能已经在select()
和之间丢失accept()
,在这种情况下,accept()
如果侦听套接字不是非阻塞的话会阻塞,这可能会阻止及时返回select()
循环并停止定期的超时处理直到另一个客户连接.
是否有任何开源库,这将有助于上述情况?
有数百个用于编写基本服务器的库,但最终您要求的内容很容易在操作系统提供的BSD套接字或Windows混合上实现.
小智 19
套接字是BI-DIRECTIONAL.如果您实际上已经剖析了以太网或串行电缆或看到了它们的低级硬件接线图,您实际上可以看到"TX"(发送)和"RX"(接收)线路的不同铜线.用于发送信号的软件,从设备控制器到大多数用于"套接字"的OS API,都反映了这一点,它是大多数系统(例如Linux)上套接字和普通管道之间的关键区别.
要真正充分利用套接字,您需要:
1)Async IO支持使用IO完成端口,epoll()或某些类似的异步回调或事件系统,以便在数据进入套接字时"唤醒".然后,必须调用最低级别的"ReadData"API以从套接字连接中读取消息.
2)支持低级写入的第二个API,一个将字节压入套接字的"WriteData"(传输),不依赖于"ReadData"逻辑所需的任何内容.请记住,即使在硬件级别,您的发送和接收也是独立的,因此不要在此级别引入锁定或其他同步.
3)Socket IO线程池,它盲目地处理从套接字读取或将被写入套接字的任何数据处理.
4)PROTOCOL CALLBACK:套接字线程具有智能指针的回调对象.它处理任何PROTOCOL层 - 例如将数据blob解析为真正的HTTP请求 - 位于基本套接字连接之上.请记住,套接字只是计算机之间的数据管道,通过它发送的数据通常会作为一系列片段(数据包)到达.在像UDP这样的协议中,数据包甚至不是有序的.低级"ReadData"和"WriteData"将从其线程回调到此处,因为它实际上是内容感知数据处理开始的地方.
5)协议处理程序本身需要的任何回调.对于HTTP,您将原始请求缓冲区打包到您传递给真实servlet的漂亮对象中,该servlet应返回一个可以序列化为符合HTTP规范的响应的良好响应对象.
请注意基本模式:如果您希望充分利用套接字上的双向异步IO,则必须使整个系统基本上处于异步状态("回调的洋葱").同时读取和写入套接字的唯一方法是使用线程,因此您仍然可以在"编写器"和"读取器"线程之间进行同步,但是只有在协议或其他考虑因素强迫我的情况下才会这样做.好消息是,使用高度异步处理的套接字可以获得出色的性能,不好的是,以强大的方式构建这样的系统是一项非常重要的工作.