繁体   English   中英

C++ 服务器,带有接收/发送命令和请求/响应设计

[英]C++ server with recv/send commands & request/response design

我正在尝试创建一个阻止 sockets 的服务器(每个新客户端一个新线程)。 该线程应该能够从客户端接收命令(并发送回结果)并定期向客户端发送命令(并请求返回结果)。

我的想法是为每个客户端创建两个线程,一个用于recv ,第二个用于send 然而:

  1. 它是正常线程开销的两倍。
  2. 由于请求/响应设计,我在第一个线程中执行的recv(等待客户端的命令)可以是我在第二个线程中查找的请求(客户端的结果到我的发送),反之亦然。 使所有内容正确同步可能是一个地狱般的故事。 所以现在我想用这种方式从一个线程中做到这一点:

在一个循环中:

  1. setsockopt(SO_RCVTIMEO, &small_timeout); //设置recv的超时时间(比如1000毫秒)。
  2. recv(); // 首先检查客户端的请求。 如果返回 WSAETIMEDOUT 比我假设没有数据被请求并且什么都不做。 如果我收到一个正常的请求,我会处理它。
  3. if (clientbufferToSend;= nullptr) send(clientbufferToSend); // 现在,当客户端的请求被处理后,我们检查我们必须发送给客户端的命令列表。 如果队列中有命令,我们发送它们。 SO_SNDTIMEO 超时可以设置为一个很大的值,这样如果客户端失去连接我们就不会死锁。
    1. setsockopt(SO_RCVTIMEO, &large_timeout); // 设置recv的超时时间(和SO_SNDTIMEO一样大,只是为了不死锁,如果有的话)。

    2. recv(); // 现在我们等待来自客户端的响应。

这是做我想做的事情的合法方式吗? 还是有更好的选择(最好是阻塞 sockets 和线程)?

PS 只有在没有数据可用的情况下,具有超时的recv()才会返回WSAETIMEDOUT吗? 如果有数据,它是否可以返回此错误,但recv()速度不够快,无法处理所有数据,从而返回部分数据?

一种方法是只创建一个后台线程来读取该套接字。 写在你的不请自来的事件引发的任何随机线程上。

你需要以下东西。

  1. 每个套接字的关键部分或互斥锁用于序列化写入,例如当后台线程正在发送对客户端发起的消息的响应时,并且其他线程想要将消息发送到同一个客户端。

  2. 其他一些同步原语,例如客户端线程在等待响应时休眠的条件变量。

  3. 接收消息的后台线程需要区分客户端发起的消息(需要由同一个后台线程响应)和对服务器发起的消息的响应。 如果您的网络协议没有该数据,您将不得不更改协议。

如果您的服务器启动的事件仅发生在单个线程上,这将正常工作,例如它们来自某些序列化源,如设备或操作系统接口。

但是,如果事件源也是多线程的,并且您希望获得良好的性能,那么您将需要不平凡的复杂性来将响应分派到正确的服务器线程,例如每个客户端线程 1 个条件变量,可能还有一些队列等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM