2014-02-20 248 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