Данные в очереди во входном буфере сокета при принудительном отключении - PullRequest
1 голос
/ 14 апреля 2019

Два совершенно разных компьютера, один под управлением Windows 7 Ultimate и один под управлением Windows Server, работают под одной и той же программой. Эта программа устанавливает сетевую архитектуру P2P между ними, используя GSocket, что указывает на то, что базовые типы сокетов зависят от платформы, следовательно, windows SOCKET.

a select() -подобная функция используется как форма обнаружения того, когда во входной очереди есть данные, и она работает безупречно. Когда клиент Windows 7 принудительно отключается, ничего не происходит, select() -подобные функции тайм-ауты, что является ожидаемым поведением (так как он может только возвращать отмененную или ошибку времени ожидания и TRUE / FALSE возвращаемое значение)

Но если одноранговый сервер Windows отключается тем же способом, это заставляет select() -подобную функцию возвращать, что есть данные во входной очереди, которая в свою очередь вызывает recv(), который завершается неудачно с (-1). В этом случае g_socket_get_available_bytes(socket) возвращает 0, так как нет байтов, что объясняет сбой recv().

Теперь это не проблема между клиентом и сервером, потому что то же самое происходит, если я меняю компьютеры так, что другой компьютер подключается. И я не знаю, как это связано с платформой, когда оба компьютера работают под управлением Windows и на обоих запущены одни и те же версии GTK +.


Что может быть причиной этого ужасно нежелательного поведения? Возможно ли, что select() -подобное поведение функции (g_socket_condition_timed_wait()) сильно отличается в дистрибутивах Windows.


По существу проблема исправлена ​​заменой g_socket_condition_timed_wait(socket, G_IO_IN, 32 * MS_SECOND, NULL, NULL); с

gboolean cnp_receive_wait_for_available_bytes (GSocket* socket/*, gint64 timeout*/)
{
    return (g_socket_get_available_bytes(socket) > 0);
}

в этом случае проверка не проходит принудительное отключение, но, если честно, я предпочитаю наоборот, если при принудительном отключении g_socket_condition_timed_wait возвращает TRUE и вызывает сбой recv, так что Мне не нужно выполнять какие-либо дополнительные проверки, чтобы обнаружить, что узел принудительно отключился.


Обновление Это не ошибка g_socket_condition_timed_wait(), я только что узнал, что

gboolean cnp_send_failed (GSocket* socket)
{ /* Probably unspecified how recv() and send() tolerates a zero-length message. */
    return(g_socket_send_with_blocking(socket, "", 0, TRUE, NULL, NULL) == (-1));
}

так же, как и g_socket_condition_timed_wait(), происходит сбой только для компьютера Windows 7, если одноранговый сервер Windows отключается, что только усугубляет проблему, так как не позволяет обнаружить, что компьютер Windows Server принудительно отключается с помощью функции, описанной выше. Я не знаю, правильно ли ОС обрабатывает закрытие каналов ввода / вывода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...