2016-11-03 114 views
1

我遇到了在asio套接字上設置no_delay選項的麻煩。下面的代碼運行良好,除了延遲。我的服務器只有在5000毫秒到期後纔會收到消息。設置ASIO no_delay選項

#include <boost/asio.hpp> 
#include <boost/thread.hpp> 
using namespace boost::asio; 
struct Client 
{ 
    io_service svc; 
    ip::tcp::socket sock; 

    Client() : svc(), sock(svc) 
    { 
     ip::tcp::resolver resolver(svc); 
     ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query("127.0.0.1", "32323")); 
     connect(sock, endpoint); 
    } 

    void send(std::string const& message) { 
     sock.send(buffer(message)); 
    } 
}; 

int main() 
{ 
    Client client; 

    client.send("hello world\n"); 
    client.send("bye world\n"); 

    boost::this_thread::sleep_for(boost::chrono::milliseconds(5000)); 
} 

當試圖增加延遲,我有幾個選擇:
1)連接之前添加的選項:

Client() : svc(), sock(svc) 
{ 
    ip::tcp::resolver resolver(svc); 
    ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query("127.0.0.1", "32323")); 

    sock.set_option(ip::tcp::no_delay(true)); 
    connect(sock, endpoint); 
} 

然而,這將引發set_option: Bad file descriptor

2)添加選項後連接:

Client() : svc(), sock(svc) 
{ 
    ip::tcp::resolver resolver(svc); 
    ip::tcp::resolver::iterator endpoint = resolver.resolve(boost::asio::ip::tcp::resolver::query("127.0.0.1", "32323")); 

    connect(sock, endpoint); 
    sock.set_option(ip::tcp::no_delay(true)); 
} 

如何在這種情況下,該選項不起作用,我仍然看到延遲。根據boost::asio with no_delay not possible?,我需要在打開套接字之後但在連接套接字之前設置選項。所以我試過這個:

Client() : svc(), sock(svc) 
{ 
    ip::tcp::endpoint endpoint(ip::address::from_string("127.0.0.1"), 32323); 
    sock.open(ip::tcp::v4()); 
    sock.set_option(ip::tcp::no_delay(true)); 
    sock.connect(endpoint); 
} 

但是,我仍然沒有看到任何效果。我怎樣才能設置這個選項?

編輯:有可能我沒有在服務器端正確設置選項。這是完整的服務器代碼:

#include <boost/asio.hpp> 
#include <iostream> 

int main() { 
    boost::asio::io_service  io_service; 
    boost::asio::ip::tcp::acceptor acceptor(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 32323)); 
    boost::asio::ip::tcp::socket socket(io_service); 

    acceptor.accept(socket); 
    socket.set_option(boost::asio::ip::tcp::no_delay(true)); 

    boost::asio::streambuf sb; 
    boost::system::error_code ec; 
    while (boost::asio::read(socket, sb, ec)) { 
     std::cout << "received:\n" << &sb; 
    } 
} 
+0

服務器是否也設置了'no_delay'選項? – Arunmu

+0

感謝您的迴應。我沒有把它設置在服務器端。我想我現在正在設置它,但仍然沒有看到效果。我編輯了原始文章以包含服務器代碼。 – Stewart

回答

2

客戶端正在正確設置ip::tcp::no_delay選項。但是,觀察到的延遲不是這個選項的結果。相反,它是服務器試圖讀取比客戶端發送更多數據的結果,並且當客戶端在睡眠5000ms後退出時,服務器的讀取操作完成並顯示錯誤。

當服務器讀取streambuf.max_size()字節或發生錯誤時,由服務器啓動的read()操作將完成。 streambuf的最大大小默認爲std::numeric_limits<std::size_t>::max(),並且可以在其constructor中進行配置。在這種情況下,服務器嘗試讀取std::numeric_limits<std::size_t>::max()個字節,但客戶端只發送22個字節,休眠5000ms,然後關閉套接字。當服務器觀察到連接已關閉時,read()操作完成,讀取的是22個字節,錯誤代碼爲boost::asio::error::eof

+0

這很有道理。我剛剛閱讀[Boost的聊天客戶端示例](http://www.boost.org/doc/libs/1_62_0/doc/html/boost_asio/example/cpp03/chat/chat_client.cpp),並試圖找出爲什麼他們在第一個字節的數據中發送緩衝區大小。這解釋了它。謝謝(你的)信息。 – Stewart