Прекратить частичное отключение пакетов UDP, когда приемный буфер почти заполнен

Я работаю над реализацией протоколов скользящего окна в C ++ для назначения. Я использую сокеты UDP (SOCK_DGRAM). Иногда программа должна отправлять большое количество пакетов (размером с размер окна). До сих пор я не увеличивал размер окна за 30, но в конечном итоге он должен достичь 256. Размер пакета должен быть взят из пользовательского ввода, так что это может быть что угодно. Когда размер пакета небольшой, например 512 байт, проблем нет. Когда размер пакета больше, например, 40 КБ, первые несколько пакетов читаются правильно, а затем внезапно моя функция readNBytes () зависает на одном из них после чтения только его части. Я предполагаю, что приемный буфер операционной системы заполняется, а часть одного из пакетов выбрасывается. Часть, которая попадает в буфер, читается, а затем readNBytes () ожидает остатка, который был отброшен ОС.

Когда это происходит, есть ли какие-либо флаги, установленные ОС для меня, чтобы прочитать? В идеале я хотел бы заставить ОС выбрасывать весь пакет, если он не помещается в приемный буфер, вместо того, чтобы просто принимать его часть. IP_DONTFRAG не определен в моей системе, поэтому я не знаю, как это сделать. Я также согласился бы на способ сделать размер приемного буфера кратным размеру моего пакета, чтобы пакет не мог частично поместиться в буфер. Каков наилучший способ преодолеть эту проблему?

0

Решение

ОС не собирается передавать половину пакета приложению.

Ответственность за фрагментацию на отправляющей стороне лежит на IP, IP-пакеты могут достигать 64 КБ и будут фрагментированы по IP, чтобы соответствовать MTU нижележащего уровня.

На приемной стороне происходит обратное, сборка. С UDP вы либо получаете весь пакет, либо ничего. Единственная причина получения только его части может заключаться в том, что буфер приема вашего приложения мал. Некоторые реализации сокетов прерывают это, даже если все было получено

0

Другие решения

Если твой recv() буфер слишком мал для дейтаграммы, он будет усечен. Это не вызывает блокировку.

Ваши датаграммы слишком велики. Ограничение IPv4 составляет 65507 байт, но общепринятый практический предел составляет 534 байта. Вы, безусловно, должны стремиться держать их под MTU пути, в противном случае вы гарантируете фрагментацию, которая только увеличивает вероятность потери дейтаграммы.

0