2016-07-12 3 views
-2

Обычно при отправке пакетов произвольного размера устанавливается максимум и используется как размер вашего буфера приема.Получить реальный размер полученного пакета

#include <winsock2.h> 

// Socket Description 
// Hint.ai_family = AF_INET; 
// Hint.ai_socktype = SOCK_DGRAM; 
// Hint.ai_protocol = IPPROTO_UDP; 

void Send(int Size) 
{ 
    char *Data = (char *)malloc(Size); 
    sendto(Socket, Data, Size, NULL, Result->ai_addr, Result->ai_addrlen) 
} 

void Receive() 
{ 
    const unsigned int MaxDataSize = 1436; 
    char *Data = (char *)malloc(MaxDataSize); 
    recvfrom(Socket, Data, MaxDataSize, 0, (SOCKADDR*)&RecvAddr, &RecvAddrSize); 
} 

В этом псевдо примере, независимо от размера данных передается Send(), наша Receive() функции всегда получает ее максимальный размер, определенный.

Как определить размер исходных отправленных пакетов?

+0

Вам нужно предоставить больше контекста, например, какой сокет это? Каков размер данных, которые вы отправляете? И вы * делаете * проверяете результат 'sendto' и' recvfrom'? Кроме того, это почти не связано с C++ (или вы будете использовать 'new' вместо' malloc'), поэтому, пожалуйста, обновите теги. Неполадка тегов. –

+3

Вы считали, что консультируетесь со страницей [* man * для * recvfrom() *] (http://linux.die.net/man/2/recvfrom)? – EJP

+2

'recvfrom' возвращает размер пакета ... – immibis

ответ

0

MSDN recvfrom() Documentation

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

Впоследствии, через использование флага MSG_PEEK:

Peeks в поступающих данных. Данные копируются в буфер, но не удаляются из входной очереди. Затем функция возвращает количество данных, которое может быть прочитано в одном вызове для функции recvfrom (или recv), которая может быть не такой, как общая сумма данных, поставленных в очередь в сокете. Объем данных, который может быть фактически равен , который считывается одним вызовом функции recvfrom (или recv), ограничен размером , размером данных, записанным в вызове функции отправки или отправки.

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

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

+0

Ваш вопрос: «Как определить размер отправленных отправленных пакетов?». Это не имеет никакого отношения к размеру буфера приема; вы пропустили это. Вы не можете сказать получателю, чтобы заполнить буфер приема или прочитать весь пакет, что бы это ни значило. Вы * должны * читать входящий пакет в несколько всплесков, период. Размер буфера приема не является проблемой. – EML

+1

@EML: то, что вы говорите, верно для TCP, но не для UDP. UDP сохраняет границы сообщений, где один вызов 'sendto()' (или связанный 'send()') отправляет полное сообщение и один вызов 'recvfrom()' (или связанный 'recv()') читает полное сообщение и возвращает его полный размер.Если буфер недостаточно велик для получения полного сообщения в одном чтении, сообщается сообщение об ошибке «WSAEMSGSIZE», и сообщение теряется, если не используется «MSG_PEEK». Нет необходимости встраивать фактическую длину сообщения в полезную нагрузку сообщения UDP, за исключением, может быть, проверки целостности. –

+0

@Remy - Я не заметил комментария UDP/DGRAM - спасибо - ответ снят. – EML

Смежные вопросы