我正在尝试创建一个带有阻塞套接字的服务器(每个新客户端一个新线程)。该线程应该能够从客户端接收命令(并发送回结果)并定期向客户端发送命令(并请求返回结果)。
我的想法是为每个客户端创建两个线程,一个用于 recv
, 第二为 send
.然而:
在一个循环中:
setsockopt(SO_RCVTIMEO, &small_timeout);
//设置recv的超时时间(比如1000毫秒)。 recv();
//首先检查客户端的请求。如果返回 WSAETIMEDOUT 比我假设没有数据被请求并且什么都不做。如果我收到一个正常的请求,我会处理它。 if (clientbufferToSend != nullptr) send(clientbufferToSend);
//现在,当客户端的请求被处理后,我们检查我们必须发送给客户端的命令列表。如果队列中有命令,我们发送它们。 SO_SNDTIMEO 超时可以设置为一个很大的值,这样如果客户端失去连接我们就不会死锁。setsockopt(SO_RCVTIMEO, &large_timeout);
//设置recv的超时时间(和SO_SNDTIMEO一样大,只是为了不死锁,如果有的话)。recv();
//现在我们等待来自客户端的响应。这是做我想做的事情的合法方式吗?还是有更好的选择(最好是阻塞套接字和线程)?
附言是否
recv()
超时返回 WSAETIMEDOUT
只有在没有数据可用的情况下?有数据能不能返回这个错误,但是recv()
处理这一切的速度不够快,因此返回了部分数据?
最佳答案
一种方法是只创建一个后台线程来读取该套接字。写在你的不请自来的事件引发的任何随机线程上。
你需要以下东西。
如果您的服务器启动的事件仅发生在单个线程上,这将正常工作,例如它们来自一些序列化的源,如设备或操作系统接口(interface)。
但是,如果事件源也是多线程的,并且您希望获得良好的性能,那么您将需要不平凡的复杂性来将响应分派(dispatch)到正确的服务器线程,例如每个客户端线程 1 个条件变量,可能还有一些队列等。
关于具有接收/发送命令和请求/响应设计的 C++ 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63092958/