- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 ASIO 编写一个允许服务器充当客户端的应用程序。例如:
我有 3 个服务器需要相互通信。在与网络中的其他服务器通信时,它们需要能够充当客户端。所有 3 个服务器都可以通过 unix 域套接字或带有 SSL 的 TCP/IP 服务请求。
这是数据流的方式:
1) 独立客户端连接到服务器 A(通过 unix 域套接字)并向其发送请求。
2) 服务器尝试响应请求,但如果不能,它会启动到服务器 B 的 TCP/IP 连接(现在服务器 A 充当服务器 B 的客户端)并将请求转发给它。服务器还“污染”数据包以告知服务器 B 不要将消息转发到另一台服务器,这样就不会产生无限循环。
3) 服务器B如果能够处理请求,则响应服务器A。
4) 如果Server B可以处理请求,Server A返回响应给standalone client。
5) 如果服务器 B 不能处理请求,服务器 A 尝试联系服务器 C、服务器 D、服务器 E 等
这有效...直到服务器 B 拥有自己的独立客户端,在服务器 A 尝试联系服务器 B 的同时尝试联系服务器 A。它会产生冲突,并且两个服务器将无限期地等待以获得响应从另一个。使用截止时间计时器我可以避免无限期等待,但它不能解决问题。
执行此操作的正确方法是什么?
编辑:我将服务器分成 2 个类(服务器和 PeerProxy)在不同的线程中运行,但我仍然遇到死锁。
这是我所做的。我已将 Unix 监听器和 TCP 监听器拆分为类 Server 和 PeerProxy。 Server 有它自己的 io_service,PeerProxy 也有它自己的。当服务器启动时,它还会启动在第二个线程中运行的 PeerProxy(因此它不会阻止服务器的执行)。现在数据的流向是这样的:
独立客户端 -> 服务器 A(无法应答) -> PeerProxy B -> 服务器 B(得到应答) -> PeerProxy B -> 服务器 A -> 独立客户端
当服务器 B 的独立客户端在服务器 A 转到 PeerProxy B 的同时转到 PeerProxy A 时,我遇到了同样的问题。
最佳答案
您应该在服务器中异步处理每个请求,即将处理分离到单独的执行线程中。这样服务器就可以保持响应,即它们可以在与其他客户端或服务器通信时对新请求使用react。
所以在你的情况下,当两个客户端 1 和 2 向服务器 A 和 B 发送请求时,只有另一个服务器可以回答(或不回答),这两个服务器可能看起来像这样:
Server A: Server B:
Thread 0 | Thread 1 | Thread 2 Thread 0 | Thread 1 | Thread 2
listen... listen...
-> req 1 -> req 2
listen... | handle req 1 listen... | handle req 2
listen... | forward to B listen... | forward to A
-> req B | wait... -> req A | wait...
listen... | wait... | handle req B listen... | wait... | reject req A
listen... | -> B: rejected | answer req B listen... | wait...
listen... | forward to C listen... | -> A: answer
listen... | -> C: answer listen... | req 2 done
listen... | req 1 done listen...
listen... listen...
在这里,每个服务器的线程 0 除了监听传入请求和处理这些请求的其他线程的旋转之外没有其他目的。其他线程通过回答请求或将其转发给所有服务器或在请求被“污染”时拒绝它来处理一个请求。
注意:这些线程根本不必是真正的线程对象。它们可以是 ASIO 异步*调用序列或某些线程框架(如 TBB)中的轻量级任务。
更新:我将为您发布一些伪代码框架,我将如何使用 Boost.Asio 实现服务器。为此,我想介绍一个我发现有助于理解 Asio 执行的小概念:您可以将其视为状态机,其中 async_*
调用是状态转换,而处理程序是状态.通常你有一个 async_*
- 每次处理程序执行调用,这意味着你从一种状态转到另一种状态。如果您在一个处理程序中有多个后续 async_*
调用,这意味着该处理程序正在生成辅助执行线程。如果处理程序不调用任何 async_*
函数,则相应的执行线程结束。
现在开始实现。
Thread 0 gies 就像典型的 Asio 教程展示的那样,创建一个套接字并监听传入的连接。唯一的事情是在每个新的客户端连接上都会产生一个新的执行线程(读取:处理程序序列):
accept_handler(client connection) {
async_read(client_request, request_handler) //spawn new thread of execution
async_accept(next client connection, accept_handler) //transition to accept_handler
}
线程 N:以 request_handler
开始:
request_handler(client_request) {
if canProcess
async_send_answer(client, done_handler) //transition to done_handler
else //relay request to first server on list
async_connect(first server on list, connect_handler) //transition to connect_handler
}
done_handler
通常会记录成功的答案并且不会调用另一个async_*
函数,这意味着与客户端的连接将被关闭并且执行线程结束。
将请求发送到其他服务器的处理程序顺序是典型的连接-发送-接收-断开顺序:
connect_handler -- async_send(request) ---------> send_handler
send_handler -- async_read(answer) ----------> read_handler
read_handler (no answer) -- async_connect(next server) --> connect_handler
如果从其中一台服务器收到答复或列表中没有更多服务器,则循环结束:
read_handler (answer ok) -- async_send_answer(client) --> done_handler
read_handler (no more servers) -- async_send_fail(client) ----> done_handler
关于c++ - boost::asio - 服务器之间的冲突,双向通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17163884/
使用 asio 库,我想为 asio::serial_port 读/写调用使用超时。 是否可以使用相同的 asio::serial_port asio::io_context 和用于 asio 的相同
对于我正在从事的副业项目应该使用哪种类型的解析器,我有点困惑。我在 asio 文档中找不到答案。 我知道 DNS 可以与 UDP 或 TCP 一起使用,并且通常通过 TCP 发送较大的响应。 asio
在仅从一个线程调用 io_service::run() 的情况下,从不同线程调用 async_write 和 async_read 是否安全?谢谢! 最佳答案 Is it safe to call a
我想知道Boost ASIO 有多受欢迎。它是否被用于任何流行的网络密集型软件中? 最佳答案 用于管理 IBM Blue Gene/Q 的系统软件 super 计算机广泛使用Boost.Asio。
我想使用一个函数来读取套接字端口,并在收到 IP 数据包时交还控制权。 boost::asio::ip::udp::socket 有一个函数接收(或 async_receive),它返回读取了多少字节
我试图调整 Boost 文档中的 SSL 服务器示例 here但我想制作一个应用程序,您可以在其中使用普通 boost::asio::ip::tcp::socket或 SSL 套接字,但我还没有找到将
在查看 boost asio co_spawn 文档 ( https://www.boost.org/doc/libs/1_78_0/doc/html/boost_asio/reference/co_
我正在尝试使用 Boost.ASIO 库,但我找不到如何列出 boost 的可用端口(带有串行端口服务)或套接字(带有网络服务)。 你知道这是否可能吗? 谢谢你。 最佳答案 Boost.Asio 不提
我想使用boost::asio从多个stdout中同时读取stderr和boost::process。但是,我在使用boost::asio时遇到了编译问题,可以重建以下无法编译的最小示例: #incl
提前为一个愚蠢的问题道歉 - 我对这一切都很陌生。 所以我从 here 下载了 asio ,并尝试#include asio.hpp,但出现以下错误; fatal error: boost/confi
我是使用 boost 的项目的一部分作为一个 C++ 库。现在我们要使用 SMTP/POP3/SSL/HTTP/HTTPS。我在 Poco::Net 中检测到几个拟合类和函数 Poco::Net::P
有谁知道有任何实现 Web Sockets 的尝试吗?使用 Boost asio 的 API? 最佳答案 我意识到这是一个旧线程,但想更新以帮助那些寻找答案的人:WebSocket++完全符合要求。
和 asio::thread_pool 有什么区别和一个 asio::io_context谁的run()函数是从多个线程调用的?我可以更换我的 boost::thread_group调用 io_con
我想连接到由目标 IP 地址和端口号指定的服务器套接字。 boost::asio::connect 似乎不允许使用它。我有 ip 目的地作为无符号 int 值。 更新:我能够做到 ba::ip::tc
我在 pc 上有 3 个网络接口(interface),并且想确保当我进行 udp 套接字发送时,它通过特定的网络接口(interface)发送(我有发送数据时使用的 ip 地址)。 这是代码。 ud
我正在使用 ASIO 开发网络应用程序并提到了Chat-Server/Client 我问过类似的问题Here 为了更好地解释,我在这里添加了更多代码: 我的 Cserver Class class C
我已经阅读了 boost asio 引用资料,浏览了教程并查看了一些示例。尽管如此,我还是看不出应该如何拆除套接字: 我应该调用 close() 还是由套接字的析构函数完成? 什么时候应该调用 shu
我认为标题已经说明了大部分内容,但我也有兴趣了解在没有现有解决方案的情况下如何将 DTLS 支持引入 asio 最佳答案 ASIO 本身不支持DTLS 但有一个GitHub 库asio_dtls已向
我正在将 async_read 与 streambuf 一起使用。但是,我想将读取的数据量限制为 4,这样我就可以在进入正文之前正确处理 header 。 我如何使用 async_read 做到这一点
从this example开始,我想用 async_read_until() 替换 async_read()。 所以我查了一下this example ,并查看了如何调用 async_read_unt
我是一名优秀的程序员,十分优秀!