Boost ASIO跨主机连接被拒求助(本地连接正常)
问题与解决方案
问题现象
在同一局域网内两台机器使用Boost ASIO建立TCP连接时,客户端抛出以下错误:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injectorboost::system::system_error>'
what(): connect: Connection refused
Aborted (core dumped)
但使用localhost进行本地连接时一切正常。
排查与解决建议
- 核实服务端IP地址:客户端代码中指定的
192.158.112.3必须是服务端机器在局域网内的真实IP,可在服务端执行ifconfig(Linux)或ipconfig(Windows)确认,避免IP输入错误。 - 检查服务端监听范围:当前服务端代码通过
tcp::endpoint(tcp::v4(), 1234)监听所有IPv4网卡,若服务端有多网卡,可显式指定局域网IP测试,例如修改为tcp::endpoint(boost::asio::ip::address::from_string("服务端局域网IP"), 1234)。 - 关闭两端防火墙:系统自带防火墙或第三方安全软件可能阻断1234端口的TCP连接,临时关闭后重试连接。
- 验证端口可达性:在客户端机器执行
telnet 192.158.112.3 1234或nc -zv 192.158.112.3 1234,测试端口是否开放。若连接失败,说明端口未被服务端正确监听或被拦截。 - 确保服务端先启动:必须等服务端程序完全启动并进入
acceptor_.accept(socket_)的等待状态后,再启动客户端。 - 修复服务端send_函数bug:原代码中拼接了带换行的
msg变量,但实际写入socket的是原message,会导致客户端读取时异常。修正后的函数如下:void send_(tcp::socket & socket, const string& message) { const string msg = message + "\n"; boost::asio::write( socket, boost::asio::buffer(msg) ); }
客户端代码
#include <iostream> #include <boost/asio.hpp> using namespace boost::asio; using ip::tcp; using std::string; using std::cout; using std::endl; int main() { boost::asio::io_service io_service; tcp::socket socket(io_service); socket.connect( tcp::endpoint( boost::asio::ip::address::from_string("192.158.112.3"), 1234 )); const string msg = "Hello from Client!\n"; boost::system::error_code error; boost::asio::write( socket, boost::asio::buffer(msg), error ); if( !error ) { cout << "Client sent hello message!" << endl; } else { cout << "send failed: " << error.message() << endl; } boost::asio::streambuf receive_buffer; boost::asio::read(socket, receive_buffer, boost::asio::transfer_all(), error); if( error && error != boost::asio::error::eof ) { cout << "receive failed: " << error.message() << endl; } else { const char* data = boost::asio::buffer_cast<const char*>(receive_buffer.data()); cout << data << endl; } return 0; }
服务端代码
#include <iostream> #include <boost/asio.hpp> using namespace boost::asio; using ip::tcp; using std::string; using std::cout; using std::endl; string read_(tcp::socket & socket) { boost::asio::streambuf buf; boost::asio::read_until( socket, buf, "\n" ); string data = boost::asio::buffer_cast<const char*>(buf.data()); return data; } void send_(tcp::socket & socket, const string& message) { const string msg = message + "\n"; boost::asio::write( socket, boost::asio::buffer(msg) ); } int main() { boost::asio::io_service io_service; tcp::acceptor acceptor_(io_service, tcp::endpoint(tcp::v4(), 1234 )); tcp::socket socket_(io_service); acceptor_.accept(socket_); string message = read_(socket_); cout << message << endl; send_(socket_, "Hello From Server!"); cout << "Server sent Hello message to Client!" << endl; return 0; }
内容的提问来源于stack exchange,提问作者James Overton
相关产品推荐
相关产品推荐

