У меня есть довольно запутанная проблема.
Я использую большую библиотеку С++ для обработки некоторого проприетарного протокола через UDP в Windows XP/7. Он прослушивает один порт на протяжении всего запуска программы и ждет соединений от удаленных аналогов.
В большинстве случаев это работает хорошо. Однако из-за некоторых проблем, которые я испытал, я решил добавить простую отладочную печать сразу после вызова WSARecvFrom
(функция win32, используемая в библиотеке, для возврата дейтаграмм из моего сокета, представляющего интерес, и сообщите, какой IP-адрес и порт, из которого они пришли).
Как ни странно, в некоторых случаях я обнаружил, что пакеты отбрасываются на уровне ОС (т.е. Я вижу их в Wireshark, у них есть правильный dst-порт, все контрольные суммы верны), но они никогда не появляются в отладочных отпечатках, которые я вложил в код).
Теперь я полностью из факта (люди часто упоминают слишком часто), что "UDP не гарантирует доставку" - но это не актуально, поскольку полученные пакеты машиной - я вижу их в Вирешарке.
Кроме того, я знаком с буферами ОС и возможностью пополнения, но здесь появляется странная часть...
Я провел некоторое исследование, пытаясь выяснить, какие пакеты упали точно. Я обнаружил, что все упавшие пакеты разделяют две общие вещи (хотя некоторые, но, безусловно, не самые, из пакетов, которые не упали, также разделяют их):
- Они маленькие. Многие из пакетов в протоколе большие, близкие к MTU, но все упавшие пакеты составляют менее 100 байт (брутто).
- Они всегда являются одним из двух: SYN-эквивалент (т.е. первый пакет, отправленный нам партнером для инициирования обмена сообщениями) или эквивалент FIN (т.е. пакет, отправленный одноранговым узлом, когда он больше не интересуется разговором для нас).
Может ли одно из этих двух качеств повлиять на буферы ОС и вызвать случайное (или даже более интересное - выборочно) удаление пакетов?
Любой свет, пролитый на эту странную проблему, будет очень оценен.
Большое спасибо.
EDIT (24/10/12):
Думаю, я, возможно, пропустил важную деталь. Кажется, что пакеты упали до прибытия, обменялись чем-то другим: они (и я начинаю верить, только они) отправляются на сервер "новыми" сверстниками, то есть сверстниками, которые он не пытался контакт до.
Например, если синэксклюзивный пакет поступает из однорангового узла *, который мы никогда раньше не видели, его не будет видеть WSARecvFrom
. Однако, если мы отправили syn-эквивалентный пакет этому равноуровню сами (даже если он не ответил в то время), и теперь он отправляет нам эквивалент, мы это увидим.
(*) Я не уверен, является ли это одноранговым узлом, которого мы не видели (т.е. ip: порт), или просто порт, который мы не видели раньше.
Помогает ли это? Это какой-то вариант WinSock, о котором я никогда не слышал? (как я уже говорил выше, код не мой, поэтому он может использовать параметры сокетов, о которых я не знаю)
Еще раз спасибо!