Потеря сетевого пакета вызывает странный код клиента - PullRequest
0 голосов
/ 06 ноября 2018

Я столкнулся с некоторыми проблемами, которые мне нужны, чтобы найти лучший способ решить эту проблему.

вот в чем проблема -

У меня работает серверный код с сокетом, который прослушивает прием новых входящих соединений.

Затем я пытаюсь запустить клиент, у которого также есть сокет, который прослушивает прием новых входящих соединений.

Код клиента начинается с принятия нового соединения в дескрипторе файла прослушивающего сокета и получает новый дескриптор файла сокета для ввода-вывода.

Сервер делает то же самое и получает новый дескриптор файла сокета для ввода / вывода.

Примечание. Клиент еще не полностью подключен. Ему нужно получить несколько байтов с сервера и отправить несколько, прежде чем он сможет запуститься.

Затем я ввожу некоторые потери пакетов при сетевом соединении TCP / IP. Это приводит к определенным ошибкам (пример: системный вызов recv () в клиентском процессе не видит принятых байтов, а затем закрывает соединение с сокетом на стороне клиента, и связанный с ним новый дескриптор файла сокета закрывается.) Однако это оставляет клиентский процесс зависание, поскольку в FD_SET есть другие дескрипторы, но ни один из них не готов к вводу / выводу. Таким образом, pselect () возвращает 0 файловых дескрипторов, готовых для ввода / вывода. Клиент должен отправить и получить определенные байты через соединение, прежде чем он сможет начать работу.

Мой вопрос больше о том, что мне здесь делать?

Я исследовал опцию SO_KEEPALIVE, когда создавал новое сокетное соединение во время системного вызова accept (). Но я не думаю, что это решило бы мою проблему здесь, особенно если потеря сетевого пакета продолжается.

Должен ли я уничтожить клиентский процесс здесь, если я понимаю, что файловые дескрипторы не готовы для ввода-вывода и никогда не будут? Есть ли лучший способ приблизиться к этому?

1 Ответ

0 голосов
/ 06 ноября 2018

Если я правильно читаю вопрос, суть вопроса заключается в следующем: «Что должна делать ваша клиентская программа, если TCP-соединение, которое является центральным для ее функциональных возможностей, было разорвано?»

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

Во многих моих собственных клиентских программах я включил логику, так что если TCP-соединение с сервером будет разорвано, клиент автоматически попытается создать новое TCP-соединение с сервером и тем самым восстановить его подключение и полезную функциональность. как можно скорее.

Другой очевидный вариант - просто завершить работу клиента при разрыве соединения; возможно, с какой-то индикацией ошибки, чтобы пользователь знал, почему клиент ушел. (возможно, появляется сообщение об ошибке, спрашивающее, хочет ли пользователь попытаться восстановить соединение?)

SO_KEEPALIVE, вероятно, не очень поможет вам в этом сценарии, кстати - несмотря на название, его цель - помочь программе более своевременно обнаружить, что соединение TCP потеряно, не , чтобы стараться сохранить соединение TCP от потери. (И это даже не очень хорошо подходит для этой цели, поскольку во многих стеках TCP отправляется только один пакет keepalive в час или около того, что означает, что даже при включенном SO_KEEPALIVE может пройти очень много времени, прежде чем ваша программа запустится получение сообщений об ошибках, отражающих потерю подключения к сети)

...