[英]C++ server with recv/send commands & request/response design
我正在尝试创建一个阻止 sockets 的服务器(每个新客户端一个新线程)。 该线程应该能够从客户端接收命令(并发送回结果)并定期向客户端发送命令(并请求返回结果)。
我的想法是为每个客户端创建两个线程,一个用于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();
// 现在我们等待来自客户端的响应。
这是做我想做的事情的合法方式吗? 还是有更好的选择(最好是阻塞 sockets 和线程)?
PS 只有在没有数据可用的情况下,具有超时的recv()
才会返回WSAETIMEDOUT
吗? 如果有数据,它是否可以返回此错误,但recv()
速度不够快,无法处理所有数据,从而返回部分数据?
一种方法是只创建一个后台线程来读取该套接字。 写在你的不请自来的事件引发的任何随机线程上。
你需要以下东西。
每个套接字的关键部分或互斥锁用于序列化写入,例如当后台线程正在发送对客户端发起的消息的响应时,并且其他线程想要将消息发送到同一个客户端。
其他一些同步原语,例如客户端线程在等待响应时休眠的条件变量。
接收消息的后台线程需要区分客户端发起的消息(需要由同一个后台线程响应)和对服务器发起的消息的响应。 如果您的网络协议没有该数据,您将不得不更改协议。
如果您的服务器启动的事件仅发生在单个线程上,这将正常工作,例如它们来自某些序列化源,如设备或操作系统接口。
但是,如果事件源也是多线程的,并且您希望获得良好的性能,那么您将需要不平凡的复杂性来将响应分派到正确的服务器线程,例如每个客户端线程 1 个条件变量,可能还有一些队列等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.