我正在尝试创建一个带有阻塞套接字的服务器(每个新客户端一个新线程)。该线程应该能够从客户端接收命令(并发送回结果)并定期向客户端发送命令(并请求返回结果)。
我的想法是为每个客户端创建两个线程,一个recv
为send
. 然而:
- 它是正常线程开销的两倍。
- 由于请求/响应设计,我在第一个线程中执行的recv(等待客户端的命令)可以是我在第二个线程中查找的请求(客户端的结果到我的发送),反之亦然。使所有内容正确同步可能是一个地狱般的故事。所以现在我想用这种方式从一个线程中做到这一点:
在一个循环中:
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();
// 现在我们等待来自客户端的响应。
这是做我想做的事情的合法方式吗?还是有更好的选择(最好是阻塞套接字和线程)?
PS只有在没有数据可用的情况下才会recv()
返回超时?WSAETIMEDOUT
如果有数据,它是否可以返回此错误,但recv()
速度不足以处理所有数据,从而返回部分数据?