发送 TCP 数据而不接收(boost asio)
Sending TCP data without recieving (boost asio)
我正在学习 boost 的 asio 教程。我正在调查他们的 chat example. More specifically, I'm trying to split their chat client 从发送者+接收者到发送者和接收者,但我看到了一些我无法解释的行为。
设置包括:
boost::asio::io_service io_service;
tcp::resolver::iterator endpoint = resolver.resolve(...);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
boost::asio::async_connect(socket, endpoint, bind(handle_connect, ... ));
发送部分实际上包括:
while (std::cin.getline(str))
io_service.post( do_write, str );
和
void do_write (string str)
{
boost::asio::async_write(socket, str, bind( handle_write, ... ));
}
接收部分包括
void handle_connect(...)
{
boost::asio::async_read(socket, read_msg_, bind(handle_read, ...));
}
void handle_read(...)
{
std::cout << read_msg_;
boost::asio::async_read(socket, read_msg_, bind(handle_read, ...));
}
如果我注释掉handle_connect
的内容来隔离发送部分,我的另一个客户端(使用原始代码编译)不会收到任何东西。如果我还原,然后注释掉 handle_read
的内容,我的另一个客户端只收到第一条消息。
为什么需要调用 async_read()
才能 post()
一个 async_write()
?
上面链接了完整的未修改代码。
这里的问题是,您的 io_service
运行 失业了,甚至在您开始发送聊天消息之前就停止处理请求。
如果您注释掉 handle_connect
的主体,那么它唯一要做的工作就是调度 handle_connect
处理程序,然后在连接完成后执行它。
std::size_t scheduler::run(asio::error_code& ec)
{
.....
mutex::scoped_lock lock(mutex_);
std::size_t n = 0;
for (; do_run_one(lock, this_thread, ec); lock.lock())
if (n != (std::numeric_limits<std::size_t>::max)())
++n;
return n;
}
所以,你必须在它的操作队列中提供一些东西。这是通过原始代码中的 handle_read_header
处理程序完成的,因为此处理程序将始终需要服务,直到客户端从服务器获取某些内容。
您可以通过向io_service
提供work
来做您想做的事。
asio::io_context io_context;
asio::io_context::work wrk(io_context); // make `run` run forever
tcp::resolver resolver(io_context);
tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
chat_client c(io_context, endpoints);
asio::thread t(boost::bind(&asio::io_context::run, &io_context));
我正在学习 boost 的 asio 教程。我正在调查他们的 chat example. More specifically, I'm trying to split their chat client 从发送者+接收者到发送者和接收者,但我看到了一些我无法解释的行为。
设置包括:
boost::asio::io_service io_service;
tcp::resolver::iterator endpoint = resolver.resolve(...);
boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
boost::asio::async_connect(socket, endpoint, bind(handle_connect, ... ));
发送部分实际上包括:
while (std::cin.getline(str))
io_service.post( do_write, str );
和
void do_write (string str)
{
boost::asio::async_write(socket, str, bind( handle_write, ... ));
}
接收部分包括
void handle_connect(...)
{
boost::asio::async_read(socket, read_msg_, bind(handle_read, ...));
}
void handle_read(...)
{
std::cout << read_msg_;
boost::asio::async_read(socket, read_msg_, bind(handle_read, ...));
}
如果我注释掉handle_connect
的内容来隔离发送部分,我的另一个客户端(使用原始代码编译)不会收到任何东西。如果我还原,然后注释掉 handle_read
的内容,我的另一个客户端只收到第一条消息。
为什么需要调用 async_read()
才能 post()
一个 async_write()
?
上面链接了完整的未修改代码。
这里的问题是,您的 io_service
运行 失业了,甚至在您开始发送聊天消息之前就停止处理请求。
如果您注释掉 handle_connect
的主体,那么它唯一要做的工作就是调度 handle_connect
处理程序,然后在连接完成后执行它。
std::size_t scheduler::run(asio::error_code& ec)
{
.....
mutex::scoped_lock lock(mutex_);
std::size_t n = 0;
for (; do_run_one(lock, this_thread, ec); lock.lock())
if (n != (std::numeric_limits<std::size_t>::max)())
++n;
return n;
}
所以,你必须在它的操作队列中提供一些东西。这是通过原始代码中的 handle_read_header
处理程序完成的,因为此处理程序将始终需要服务,直到客户端从服务器获取某些内容。
您可以通过向io_service
提供work
来做您想做的事。
asio::io_context io_context;
asio::io_context::work wrk(io_context); // make `run` run forever
tcp::resolver resolver(io_context);
tcp::resolver::results_type endpoints = resolver.resolve(argv[1], argv[2]);
chat_client c(io_context, endpoints);
asio::thread t(boost::bind(&asio::io_context::run, &io_context));