Теряются/бьются UDP пакеты на localhost, так и должно быть?
Здравствуйте.
Две программы общаются между собой по UDP на localhost. Одна из них моя, на Qt.
Проблема в том, что бьются данные в пакетах.
Я думал на localhost такого впринципе не может быть, я ошибаюсь?
Или проблема в самом QUdpSocket из Qt ?
Kalombyr , а конкретика где?
Какой у тебя трафик? Какой размер датаграммы? Какая частота опроса сокета тут и там?
С какими флагами делаешь отсылку и прием датаграмм?
Евгений Шатунов, извините, пропустил уведомления.
Размер каждой датаграммы примерно 1 Кб (ко мне, от себя ну максимум 10 байт)
У себя при создании сокета ставлю QUdpSocket::ShareAddress | QUdpSocket::QUdpSocket::ReuseAddressHint какие у другой программы не смотрел.
Трафик варьируется но максимум что видел 2Мб/с
У себя опрос организован в отдельном потоке с высоким приоритетом.
обмен происходит через разные порты, с одного отсылаю, на другой принимаю - так же сделано и на другой программе.
Kalombyr, ясно. У тебя тут, вероятно, целый букет заболеваний. И я ведь правильно понимаю что ты не проверяешь ошибку при отправке данных в своем коде?
Конкретику я все так же не могу выдать потому что по такому описанию надо смотреть код. А это может занять много времени, чего я не могу тебе предоставить.
Поэтому я просто опишу то, что подозреваю исходя из твоего описания.
Короткие датаграммы - это хорошо. В локальной петле MTU имеет размер 64КБ. Пакеты в 1КБ - это уже хорошо.
Шаринг сокета - это одна из причин потери пакетов. Вот попробуй угадать, кто должен принять трафик, когда сокет одновременно читают N клиентов? Там просто кто первый прочитал, того и тапки.
Пакеты в локальной петле для протокола UDP теряться будут только если ты их шлешь без меры. У локальной петли есть свой промежуточный буфер для передаваемых данных. Когда этот буфер забивается данными, а на том конце их так и не начали читать, sendto возвращает тебе ошибку, которую ты должен разобрать и понять.
Поэтому я и подозреваю что у тебя ошибки не обрабатываются.
Проверь попутно размеры буфера приема и буфера отправки в своем сокете. Это делается через getsockopt или его аналог для Qt. В POSIX свойства называются SO_RCVBUF и SO_SNDBUF.
Евгений Шатунов, спасибо за развёрнутый ответ.
1. Эм, используется фреймворк Qt, насколько я проверял чисто между своими программами UDP сокеты работают отлично на высоких скоростях. Ошибки везде где только могу проверяю в плане отправилось ли или нет.
2. Шаринг просто навсякий случай обычно ставлю, убирать пробовал.
По поводу буфера возможно Вы правы, т.к. устанавливая задержки между отправками от меня ситуация улучшается. Попробую ещё нативными методами работать с сокетами, возможно действительно будет лучше ибо хз что Qt добавил от себя.
На данный момент уже написал обёртку над WS2_32.dll что бы вообще уйти от сокетов и работать с программой напрямую перехватывая вызовы записи/чтения может быть получится.
Потеря пакетов на localhost может быть, если очень много данных. Просто буфер где-то кончается и все.
А вот битые данные - это уже 100% где-то у вас в программах ошибки.
Вы ошибаетесь. проблема в вашей программе.
Сделайте следующее:
в программе сделайте логгирование в формате вайршарка, так вы точно получите материал для сравнения.
Вайршарком захватите сессию, так вы точно поймете что идет в сеть, сравнивайте и правьте код