【发布时间】:2017-06-22 19:28:20
【问题描述】:
我是一名 57 岁的 AspNet 程序员。因为我是唯一一个用 C++ 工作过的人,所以我的老板要求我为需要具有非常特殊特征的通信代理的客户提供服务。它可以在多个平台上作为守护进程运行,有时既是客户端又是服务器。我知道的不够多,但我必须解决问题,并在 Boost / Asio 库中找到了机会。
我是 Boost-Asio 的新手,阅读文档后,我创建了一个服务器和一个 TCP 套接字客户端,可以完美地双向、全双工地交换消息。
我阅读了几篇他们要求我想要的相同东西的帖子,但所有答案都建议全双工,好像这意味着在同一个程序中拥有一个客户端和一个服务器。事实并非如此。全双工的定义是指可以在同一个连接上读写,每个TCP连接默认都是全双工的。
我需要让两个程序可以接受对方发起的连接。这两个程序之间不会有永久的联系。有时其中一个会请求连接,而在其他时候另一个会发出这个请求,并且两者都需要监听、接受连接、交换一些消息并终止连接,直到发出新的请求。
我做的服务器似乎在侦听端口以查看是否有连接的过程中卡住了,我无法继续该过程以创建套接字并请求与其他程序的连接.我需要线程,但我对它们了解不够。
有可能吗?
正如我所说,我是 Boost / Asio 的新手,我尝试关注一些关于线程和协程的文档。然后我将客户端代码放在一个方法中,将服务器放在另一个方法中。:
int main(int argc, char* argv[])
{
try
{
boost::thread t1(&server_agent);
boost::thread t2(&client_agent);
// wait
t1.join();
t2.join();
return 0;
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
还有两个协程:
void client_agent() {
parameters param;
param.load();
boost::asio::io_service io_service1;
tcp::resolver resolver(io_service1);
char port[5];
_itoa(param.getNrPortaServComunic(), port, 10);
auto endpoint_iterator = resolver.resolve({ param.getIPServComunicPrincipal(), port });
std::list<client> clients;
client c(io_service1, endpoint_iterator, param);
while (true)
{
BOOL enviada = FALSE;
while (true) {
if (!enviada) {
std::cout << "sending a message\n";
int nr = 110;
message msg(nr, param);
c.write(msg);
enviada = TRUE;
}
}
}
c.close();
}
void server_agent() {
parameters param;
param.load();
boost::asio::io_service io_service1;
std::list<server> servers;
tcp::endpoint endpoint(tcp::v4(), param.getNrPortaAgenteServ());
servers.emplace_back(io_service1, endpoint);
io_service1.run();
}
我使用一个端口到客户端端点,另一个端口到服务器端点。这是正确的吗?需要吗?
它开始看起来好像可以工作了。每个方法都同时运行,但随后我在 io_service1.run(server_agent 方法的最后一行)处遇到线程分配错误:
boost::exception_detail::clone_impl > 在内存位置 0x0118C61C。
有什么建议吗?
【问题讨论】:
-
至于标题,我很确定您可以使用 boost asio 实现全双工服务器/客户端客户端/服务器。只需为进程和客户端连接启用
boost::acceptor。只需异步处理所有内容。 -
谢谢。我会尝试这种方法。这似乎是不陷入循环的唯一方法。
标签: c++ multithreading sockets boost