带有asio的多套接字架构

multi socket architecture with asio

本文关键字:套接字 asio 带有      更新时间:2023-10-16

我有一个客户端-服务器体系结构,有10个服务器,与一个客户端永久连接,该软件用C++编写,并使用boost asio库。所有连接都是在初始化阶段创建的,并且在执行过程中始终处于打开状态。当客户端需要一些信息时,会向所有服务器发送一个请求。每个服务器都能找到所需的信息并回答客户端的问题。

在客户端中,有一个线程负责接收来自所有套接字的消息,特别是,我只使用一个io_services和来自每个套接字的一个async_read。

当消息到达其中一个套接字时,async_read读取作为消息头的前N位,然后调用使用read(同步)读取消息其余部分的函数。对于服务器端,标头和消息的其余部分使用单个write(同步)发送。

然后,体系结构可以正常工作,但我注意到,有时同步read比平时花费更多的时间(~0.24秒)。理论上,数据准备好被读取,因为同步read是在async_read已经读取报头时被调用的。我还发现,如果我只使用一台服务器而不是10台,就不会出现这个问题。此外,我注意到这个问题并不是因为消息的维度造成的。

是否可能是因为io_service无法处理所有10个async_read而出现问题?特别是,如果所有套接字都同时接收到一条消息,io_service是否会浪费一些时间来管理队列,并降低我的同步read的速度?

我还没有发布代码,因为很难从项目中提取出来,但如果你不理解我的描述,我可以写一个例子。

谢谢。

1)当async.read完成处理程序被调用时,并不意味着某些数据可用,而是意味着此时所有可用的数据都已被读取(除非您指定了限制完成条件)。因此,后续的sync.read可能要等到更多的数据到达。

2) 阻塞一个完成处理程序是个坏主意,因为实际上您阻塞了发布到该io_service的所有其他完成处理程序和其他函数。考虑更改您的设计。

如果你选择异步设计,不要混合一些同步部分。用异步读写操作替换所有同步读写操作。读取和写入都会阻塞线程,而异步变体则不会。

此外,如果您在读取标头后准确地知道期望的字节数,那么您应该请求该字节数。

如果你不知道,你可以选择一个async_read_some,它的大小相当于你期望的最大消息。async_read_some将通知您实际读取了多少字节。