2011-11-03 4 views
3

UDP를 통해 C 구조체를 보내고 있습니다.C에서 가변 길이의 UDP 패킷을 읽는 법

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

[numInt][intList[0]]...[intList[numInt-1]]으로 직렬화됩니다.

버퍼가 많은 바이트를 보유하지 않더라도 나의 이해는 UDP에서 recvfrom를 호출하면 전체 패킷을 읽습니다. 내가 가진 유일한 옵션은 정말 큰 버퍼를 사용하고 있습니까?

답변

4

MSG_PEEKrecvfrom에 전달하면 버퍼의 크기를 정확하게 알 수 있습니다. 따라서 단지 recvfromMSG_PEEK으로 몇 바이트로 numInt을 찾은 다음 recvfrom을 찾으십시오 (이번에는 MSG_PEEK없이).

The standard 말한다 무언가에 대한 MSG_PEEK하지만 kernel.org 주문 더 나은 :

MSG_PEEK

이 플래그는에서 데이터를 제거하지 않고받는 큐의 처음부터 데이터를 반환하는 받기 작동을하도록한다 대기열. 따라서 후속 수신 호출은 동일한 데이터를 리턴합니다.

분명히 어떤 시점에서 메모리를 절약하기 위해 시스템 호출 횟수를 두 배로 늘릴만한 가치가 있는지 궁금해하게 될 것입니다. 나는 그렇지 않다고 생각한다.

-2

나는 recvfrom이 3 번째 인자 인 len으로 말한만큼 많은 바이트를 읽을 것이라고 확신한다. 사용할 수있는 바이트 수가 적은 경우, 거기에있는 것을 반환합니다. 그 이상이 있으면 len 바이트까지 되돌려줍니다. 예상하고있는 모든 데이터를 얻기 위해 추가 전화를해야 할 수도 있습니다.

+3

표준은 다음과 같이 말합니다 : "메시지가 너무 길어서 제공된 버퍼에 맞지 않고 MSG_PEEK가 flags 인수에 설정되지 않은 경우 초과 바이트는 버려집니다 **. *" . 'SOCK_DGRAM'은 이와 관련하여'SOCK_STREAM'과 다릅니다. – cnicutar

0

플래그가 설정된 numInt을 얻기에 충분한 크기의 작은 버퍼를 사용해보십시오. 그러면 실제로 필요한 크기를 알 수 있고 MSG_PEEK없이 다시 수신하면 모든 것을 얻을 수 있습니다.

2

UDP 패킷은 전체적으로 보내고받습니다. 을 받으면 크기가 맞습니다. read() 또는 recv() 또는 recfrom()에 충분히 큰 버퍼를 제공해야합니다. 페이로드 내부의 길이 필드는 중복됩니다. read()가 정확한 크기를 알려주기 때문입니다. 동일한 바이트 순서를 갖는 발신자와 수신자에 의존하기 때문에 위험합니다.

+0

발신자와 수신자가 자신의 바이트 순서를 이해하지 못한다면 요점은 무엇입니까? –

관련 문제