Как прочитать UDP-пакет с переменной длиной в C - PullRequest
3 голосов
/ 04 ноября 2011

Я отправляю структуру C по UDP

struct packet{
    int numInt;
    int* intList; //malloc'ed as (sizeof(int)*numInt)
}

Она будет сериализована как [numInt][intList[0]]...[intList[numInt-1]].

Насколько я понимаю, вызов recvfrom в UDP будет читать всепакет, даже если буфер не содержит столько байтов.Является ли использование действительно большого буфера единственным вариантом, который у меня есть?

Ответы [ 4 ]

5 голосов
/ 04 ноября 2011

Вы можете передать MSG_PEEK в recvfrom, чтобы точно определить, насколько большим должен быть буфер. Так что просто recvfrom несколько байтов с MSG_PEEK, чтобы найти numInt, а затем recvfrom реальную вещь (на этот раз без MSG_PEEK).

Стандарт что-то говорит о MSG_PEEK, но kernel.org лучше говорит:

MSG_PEEK

Этот флаг заставляет операцию приема возвращать данные из начало очереди приема без удаления этих данных из очередь. Таким образом, последующий приемный вызов вернет те же данные.

Очевидно, что в какой-то момент вы начнете задумываться, стоит ли удвоение количества системных вызовов для экономии памяти. Я думаю, что это не так.

3 голосов
/ 04 ноября 2011

UDP-пакеты отправляются и принимаются в целом. если вы его получите, то размер правильный.Единственное, что вам нужно сделать, это предоставить достаточно большой буфер для read () или recv () или recfrom ().Поле длины внутри полезной нагрузки является избыточным, так как read () сообщит вам правильный размер.Это также опасно, поскольку отправитель и получатель имеют одинаковый порядок байтов.

0 голосов
/ 04 ноября 2011

Вы можете попробовать использовать небольшой буфер, достаточно большой, чтобы получить numInt, с установленным флагом MSG_PEEK.Затем вы можете узнать нужный вам размер и получить снова без MSG_PEEK, чтобы получить все.

0 голосов
/ 04 ноября 2011

Я почти уверен, что recvfrom будет считывать столько байтов, сколько ему сообщит третий аргумент, len Если доступно меньше байтов, он вернет то, что есть. Если их больше, он вернется до длинных байтов. Возможно, вам придется сделать дополнительные звонки, чтобы получить все данные, которые вы ожидаете.

...