Здравствуйте, пишу клиент-сервер основываясь на UDP протоколе, все сделал дебажа на локал хосте, но когда решил затестить приложение уже в локальной сети то столкнулся с иной проблемой, а именно - пакеты иногда теряются, даже если я выключу инет и оставлю только wi-fy. В чем может быть проблема, на локал хосте все работает максимально правильно. Не знаю что делать в такой ситуации, прошу вашей помощи.
-
2UDP подразумевает, что проверка ошибок и исправление либо не нужны, либо должны исполняться в приложении. https://ru.wikipedia.org/wiki/UDP Этот протокол легко позволяет терять пакеты по причинам, описанными по ссылке выше. – Jun 03 '16 at 00:12
-
Если вам дан исчерпывающий ответ, отметьте его как верный (галка напротив выбранного ответа). – Nicolas Chabanovsky Jun 10 '16 at 06:15
2 Answers
UDP-пакеты имеют право теряться, всё в порядке. Это ожидаемое поведение. Если вам нужна гарантированная доставка, используйте TCP.
Или вы можете отправлять на сервер подтверждение приёма, и при отсутствии такого подтверждения повторять передачу. Но такой велосипед будет по сути повторять то, что делает TCP внутри.
- 206,799
-
я решил переделать логику под TCP, теперь у меня начались очень странные проблемы... а именно при отправке файлов у меня идет такая последовательность а) клиент(принимает файл):
- Send (пустое сообщение, что бы соинхрнизироваться)
- Receive - получаю инфу о файле
Цикл (пока не придет уведомление что конец файла) 3. Receive - 1 пакет 4. Send (пустое сообщение) для уведомления о том, что я закончил преобразование пакета конец цикла (после цикла, сохраняю файл)
Сервер (отправитель) (тоже самое но инвертирую) Сейчас допишу
– simply good Jun 03 '16 at 20:41 -
б Сервер:
- Receive - получим пустое сообщение о готовности
- Send - инфа о файле
цикл для всех пакетов 3. Send - отправляем 1 пакет 4. Receive - Жду подтвержения (пустое сообщение) конец цикла 5. Send - конец отправки фала (в цикле клиента проверется, я пояснил перед объявлением цикла)
– simply good Jun 03 '16 at 20:46 -
Собственно, это работало отлично на локал хосте на протоколе UDP, теперь на TCP возникает очень странная ситуация, что даже при такой синхронизации, где-то либо клиент, либо сервер могут застыть (чаще сервер) и все... Реши проблему странным образом (а может не решил, но ошибок не было) установил в начале каждой итерации сон для потока на 15мс – simply good Jun 03 '16 at 20:49
-
Но в другом месте, где вызываю этот метод на прием, все равно... Может возникнуть такой дедлок, и оба приложения, что клиент, что сервер застынут. – simply good Jun 03 '16 at 20:50
-
Повторю вопрос, что за бред? почему на UDP (127,0,0,1) все работало отлично, а теперь с TCP, все работает ужасно, если можно так выразится(тоже Local host), я уже не знаю какие мне костыли пихать..., – simply good Jun 03 '16 at 20:52
-
Даже в некоторых моментах, при тех же условиях, может зависнуть выполнение – simply good Jun 03 '16 at 20:55
-
@simplygood: О TCP это уже следующий вопрос. И по идее мне кажется, что не стоит делать такой сложный обмен сообщениями (но это не тема данного вопроса). – VladD Jun 03 '16 at 21:18
теперь на TCP возникает очень странная ситуация, что даже при такой синхронизации, где-то либо клиент, либо сервер могут застыть (чаще сервер) и все...
Возможно потому что TCP использует блокирующие сокеты для связи. Для того чтобы подключение, прием, отправка сообщений не останавливали поток, либо выделяйте операцию в отдельном потоке (для простоты можно использовать класс BackGroundWorker), либо используйте асинхронные методы BeginAccept, BeginReceive, BeginSend, BeginConnect.
Очень хорошо разница между синхронными и асинхронными запросами описана тут Нужен async/await или не нужен?
Или вот вам подробный пример TCP клиент-сервера https://www.youtube.com/watch?v=xgLRe7QV6QI
Если все же решите дальше исследовать вопрос с UDP, то для предотвращения потери пакетов обычно пишут обертку над UPD обеспечивающую подтверждение каждого доставленного пакета. Если для какого либо пакета не пришел ответ о доставке, его посылают заново. Для отправки больших пакетов их "вручную" фрагментируют на части, каждый из которых подписывается.
Организовать очередь пакетов на отправку можно по разному, например циклическим массивом.
- 319