Два совершенно разных компьютера, один под управлением 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 принудительно отключается с помощью функции, описанной выше. Я не знаю, правильно ли ОС обрабатывает закрытие каналов ввода / вывода.