2016-11-03 3 views
1

У меня возникли проблемы с настройкой опции no_delay на гнездо asio. Следующий код работает хорошо, за исключением задержки. Мой сервер получает сообщения только после истечения 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. Однако наблюдаемая задержка не является результатом этого варианта. Вместо этого это результат того, что сервер пытается прочитать больше данных, чем клиент отправил, а когда клиент выходит после спящего 5000 мс, операция чтения сервера завершается с ошибкой.

Операция read(), инициированная сервером, будет завершена, если либо он прочитал streambuf.max_size() байт, либо возникла ошибка. Максимальный размер streambuf по умолчанию равен std::numeric_limits<std::size_t>::max() и может быть настроен в его constructor. В этом случае сервер пытается прочитать std::numeric_limits<std::size_t>::max() байт, но клиент отправляет только 22 байта, спит 5000 мс, а затем закрывает сокет. Когда сервер замечает, что соединение закрыто, операция 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

Смежные вопросы