boost :: asio :: read () никогда не возвращается, даже после успешного выполнения write () на другом конце - PullRequest
1 голос
/ 17 октября 2011

Я пытаюсь выучить boost :: asio для сокетов / сетевого программирования. Я пытаюсь отправить некоторые простые данные с клиента на сервер.

Позвольте мне прежде всего сказать, что я намеренно использую синхронный блокирующий код, в отличие от асинхронного неблокирующего кода, потому что я использую многопоточность (с библиотекой pthreads) в дополнение к это.

Клиент успешно вызывает boost :: asio :: write (). Я зашел так далеко, что не только пытался перехватить любые исключения, генерируемые boost :: asio :: write (), но и проверить значение boost :: system :: error_code, которое выдает сообщение «Операция была завершено успешно "или что-то в этом роде.

Мой код read () выглядит следующим образом:

#define MAX_MESSAGE_SIZE 10000 // in bytes
void* receivedData = malloc(MAX_MESSAGE_SIZE);

try
{
    boost::asio::read(*sock, boost::asio::buffer(receivedData, MAX_MESSAGE_SIZE));
}
catch (std::exception &e)
{
    std::cout << "Exception thrown by boost::read() in receiveMessage(): " << e.what() << "\n";
    delete receivedData;
    receivedData = NULL;
    return false;
}

Несмотря на то, что write () успешно выполняется на другом конце, и клиент и сервер соглашаются, что на этом этапе установлено соединение, read () никогда не возвращается. Единственный случай, когда он возвращается для меня, - это если я вручную закрываю клиентское приложение, и в этот момент (как и следовало ожидать) вызов read () выдает исключение, указывающее, что клиент принудительно закрыл соединение.

Имеет ли это какое-либо отношение к io_service.run ()? В моем поиске в Google, я наткнулся на некоторые упоминания о run (), и я неявно собрал из этих сообщений то, что run () обрабатывает «работу», что, как я понимаю, означает фактическую отправку и получение и то, что write () и read () - это всего лишь средство постановки в очередь отправки и проверки того, какие пакеты уже были отправлены и, так сказать, «одобрены» с помощью io_service.run (). Пожалуйста, исправьте меня, если я ошибаюсь, поскольку документация Boost говорит чуть больше, чем «Выполнить цикл обработки событий io_service».

Я следую учебному пособию boost :: asio (http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/tutorial/tutdaytime1.html), в котором абсолютно не упоминается run (), так что, возможно, я здесь не на том пути, и run () не требуется вообще?

В любом случае, просто сейчас я сделал другое изменение в своем коде, чтобы посмотреть, изменится ли что-нибудь (не изменилось): и на моем клиенте, и на сервере я настроил поток для следующей функции (для вызова io_service.run () несколько раз в течение всего срока действия приложения, чтобы выяснить, не является ли это причиной проблемы):

void* workerThread(void* nothing)
{
    while(1)
    {
        io_service.run();
        Sleep(10); // just keeping my CPU from overheating in this infinite loop
    }
}

Но, как указано выше, это никак не повлияло на производительность.

Что мне здесь не хватает? Почему read () никогда не возвращается даже после успешного выполнения write () на другом конце?

Заранее спасибо.

1 Ответ

2 голосов
/ 17 октября 2011

Обратите внимание, что чтение, которое вы используете, будет блокироваться до тех пор, пока буфер не заполнится или не произойдет ошибка - поэтому он вернется только после получения 10000 байт.

Рассмотрите возможность использования read_some или условия завершения с readвместо этого.

...