2014-02-20 162 views
0

我想设置一个套接字的超时,我已经创建使用ASIO提升没有运气。我发现下面的代码的其他地方网站上:设置流的ASIO超时

tcp::socket socket(io_service); 
    struct timeval tv; 
    tv.tv_sec = 5; 
    tv.tv_usec = 0; 
    setsockopt(socket.native(), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); 
    setsockopt(socket.native(), SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); 
boost::asio::connect(socket, endpoint_iterator); 

超时保持在相对于话,5秒我要寻找一个在连接调用相同的60秒。我错过了什么?请注意,连接代码在所有其他情况下都可以正常工作(没有超时)。

回答

1

您设置的套接字选项不适用于connect AFAIK。 这可以通过使用异步asio API来完成,如下面的asio example

有趣的部分设置超时处理程序:

deadline_.async_wait(boost::bind(&client::check_deadline, this)); 

启动定时器

void start_connect(tcp::resolver::iterator endpoint_iter) 
{ 
    if (endpoint_iter != tcp::resolver::iterator()) 
    { 
    std::cout << "Trying " << endpoint_iter->endpoint() << "...\n"; 

    // Set a deadline for the connect operation. 
    deadline_.expires_from_now(boost::posix_time::seconds(60)); 

    // Start the asynchronous connect operation. 
    socket_.async_connect(endpoint_iter->endpoint(), 
     boost::bind(&client::handle_connect, 
     this, _1, endpoint_iter)); 
    } 
    else 
    { 
    // There are no more endpoints to try. Shut down the client. 
    stop(); 
    } 
} 

和关闭这将导致在连接完成处理程序运行的插座。

void check_deadline() 
{ 
    if (stopped_) 
    return; 

    // Check whether the deadline has passed. We compare the deadline against 
    // the current time since a new asynchronous operation may have moved the 
    // deadline before this actor had a chance to run. 
    if (deadline_.expires_at() <= deadline_timer::traits_type::now()) 
    { 
    // The deadline has passed. The socket is closed so that any outstanding 
    // asynchronous operations are cancelled. 
    socket_.close(); 

    // There is no longer an active deadline. The expiry is set to positive 
    // infinity so that the actor takes no action until a new deadline is set. 
    deadline_.expires_at(boost::posix_time::pos_infin); 
    } 

    // Put the actor back to sleep. 
    deadline_.async_wait(boost::bind(&client::check_deadline, this)); 
} 
+0

谢谢。我刚才发现他们不适用于连接。我准备拼凑一个计时器来执行我自己的SIG处理。我更喜欢你的方式。 – mlewis54

+0

好的很好:)这不是我的方式,它来自asio作者Chris Kohlhoff的例子。 – Ralf

+0

这是一个很好的解决方案Ralf,我通常做同样的事情,我使用现有的asio :: io_service来定时器来处理我的超时。我唯一额外的补充是你可以绑定一个回调以在超时执行。如果你的系统想要/需要一个超时发生的通知来执行一些清理,重试或其他这样的事情而不停止套接字,那么你可以把它的代码放在定时器过期回调中。 – OcularProgrammer