场景
boost库中的asio模块,在阻塞模式下,调用connect进行服务器的连接,如果服务器没有打开,默认情况下需要20秒的超时连接,才会返回。目前尝试设置套接字的连接超时时间,都不奏效。估计只能修改boost源码中的超时时间
//设置成非阻塞,然后调用select等待超时,无效
int TestBoostAsioConnectTimeout()
{
boost::asio::io_service ios;
boost::asio::ip::tcp::socket sock(ios);
boost::system::error_code ec;
sock.open(boost::asio::ip::tcp::v4());
// 设为非阻塞
sock.io_control(boost::asio::ip::tcp::socket::non_blocking_io(true));
sock.connect(
boost::asio::ip::tcp::endpoint(
boost::asio::ip::address::from_string("192.168.1.1"), 80)
, ec);
fd_set fdWrite;
FD_ZERO(&fdWrite);
FD_SET(sock.native(), &fdWrite);
timeval tv = { 5 }; // 5秒超时
if (select(0, NULL, &fdWrite, NULL, &tv) <= 0
|| !FD_ISSET(sock.native(), &fdWrite))
{
std::cout << "连接超时" << std::endl;
sock.close();
return 0;
}
// 设回阻塞
sock.io_control(boost::asio::ip::tcp::socket::non_blocking_io(false));
std::cout << "连接成功" << std::endl;
sock.close();
return 0;
}
//获取原始的套接字,进行属性的设置
int TestBoostAsioConnectOverTime()
{
boost::asio::io_service ios;
boost::asio::ip::tcp::socket sock(ios);
boost::system::error_code ec;
sock.open(boost::asio::ip::tcp::v4());
// 设为非阻塞
sock.io_control(boost::asio::ip::tcp::socket::non_blocking_io(true));
int timeout = 3000;
int nRet = setsockopt(sock.native(), SOL_SOCKET, SO_CONNECT_TIME, (const char*)&timeout, sizeof(timeout));
nRet = setsockopt(sock.native(), SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
sock.connect(
boost::asio::ip::tcp::endpoint(
boost::asio::ip::address::from_string("192.168.1.1"), 80)
, ec);
fd_set fdWrite;
FD_ZERO(&fdWrite);
FD_SET(sock.native(), &fdWrite);
timeval tv;
tv.tv_sec = 1; // 5秒超时
tv.tv_usec = 0;
if (select(0, NULL, &fdWrite, NULL, &tv) <= 0
|| !FD_ISSET(sock.native(), &fdWrite))
{
std::cout << "超时/出错啦" << std::endl;
sock.close();
return 0;
}
// 设回阻塞
sock.io_control(boost::asio::ip::tcp::socket::non_blocking_io(false));
std::cout << "连接成功" << std::endl;
sock.close();
return 0;
}
设置超时的代码:
windows:
int nTvlen=1000; //1s
int retOpt=setsockopt(m_Socket,SOL_SOCKET, SO_RCVTIMEO, (const char*)&nTvlen,sizeof(nTvlen));
linux:
struct timeval nTvlen={1,0}; //1S
int retOpt=setsockopt(m_Socket,SOL_SOCKET, SO_RCVTIMEO, (const char*)&nTvlen,sizeof(nTvlen));
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。