boost::asio同步write成功写入Socket,为何服务器未接收数据?
同步写入TCP Socket后服务器未接收数据的问题
我写了一段简单代码,向Docker同一网络下的tcp-server-echo容器(基于istio/tcp-echo-server:1.2镜像)的TCP回显服务器写入数据。代码里writtenBytes > 0显示数据已成功写入Socket,但服务器始终没有反馈接收数据。开发容器能ping通服务器容器,而且改用异步解析、异步连接(写入仍同步)并单独线程运行io_service时,服务器能正常接收并响应。
代码示例:
io_service ioservice; tcp::socket tcp_socket{ioservice}; void TestTcpConnection() { boost::asio::ip::tcp::resolver nameResolver{ioservice}; boost::asio::ip::tcp::resolver::query query{"tcp-server-echo", "9000"}; boost::system::error_code ec{}; auto iterator = nameResolver.resolve(query, ec); if (ec == 0) { boost::asio::ip::tcp::resolver::iterator end{}; boost::asio::ip::tcp::endpoint endpoint = *iterator; tcp_socket.connect(endpoint, ec); if (ec == 0) { std::string str{"Hello world test"}; while (tcp_socket.is_open()) { auto writtenBytes = boost::asio::write(tcp_socket, boost::asio::buffer(str)); if (writtenBytes > 0) { // 这段代码每次都能执行成功 // writtenBytes等于13,和str.length()一致 std::cout << "Bytes written successfully!\n"; } using namespace std::chrono_literals; std::this_thread::sleep_for(2000ms); } } }
问题原因分析
核心问题出在Boost.Asio的io_service没有被运行。
Boost.Asio的同步操作看似是阻塞式,但底层依然依赖io_service的事件循环来完成底层I/O的完成通知。你的同步代码里只调用了同步的resolve、connect和write,但从未启动io_service的事件循环(比如调用ioservice.run())。
虽然同步操作本身会阻塞直到完成,但部分平台的I/O实现中,io_service需要处理后续的清理或确认操作,否则数据可能卡在缓冲区里没有真正发送到网络。而改用异步API并单独线程运行ioservice.run()时,事件循环正常运转,底层I/O操作能完整执行,数据也就顺利发送到了服务器。
解决办法
在同步代码中必须调用ioservice.run(),可以选择以下两种方式:
- 在主线程启动测试函数后运行
io_service:
int main() { std::thread t(TestTcpConnection); ioservice.run(); t.join(); return 0; }
- 在测试函数内部,连接成功后启动后台线程运行
io_service:
if (ec == 0) { std::thread([&](){ ioservice.run(); }).detach(); std::string str{"Hello world test"}; // 后续的写入循环... }
另外补充:boost::asio::write本身就是阻塞直到所有数据写入完成,所以writtenBytes > 0的判断其实多余,只要没有抛出异常(或错误码)就说明数据写入成功。
内容的提问来源于stack exchange,提问作者YesButWhy
相关产品推荐
相关产品推荐

