2010-03-30 6 views
7

리눅스에서 유닉스 소켓 API를 사용하면, 하나의 UDP 패킷과 단 하나의 UDP 패킷을 읽게 할 수있는 방법이 있습니까? 현재 recvmsg를 사용하여 비 차단 소켓에서 패킷을 읽는 중입니다. 버퍼 크기는 내부 네트워크의 MTU보다 약간 큽니다. 이렇게해야 항상 전체 UDP 패킷을받을 수 있지만 패킷이 작 으면 recvmsg 호출 당 둘 이상의 패킷을 수신하지 못할 것이라고 확신 할 수는 없습니다.정확히 하나의 UDP 패킷을 소켓에서 읽을 수 있습니까?

recvmsg 매뉴얼 페이지는 버퍼가 채워질 때까지 대기를 시도하는 MSG_WAITALL 옵션을 참조합니다. 우리는 이것을 사용하지 않고있다. 그래서 그것은 하나의 데이터 그램이 읽힌 후에 recvmsg가 항상 리턴한다는 것을 의미 하는가? 이것을 보장 할 방법이 있습니까?

이상적으로는 유닉스 계열의 솔루션을 원합니다. 그러나 존재하지 않는다면 리눅스에 특정한 것이 있습니까?

+1

MSG_WAITALL은 스트림 지향 소켓 용입니다. http://linux.die.net/man/3/recvmsg 이미 응답 한대로 recv/send()는 데이터 그램 지향 소켓에 대해 전체 데이터 그램을 사용하여 작동합니다. – Ioan

답변

12

recvmsg은 하나의 패킷을 반환하며, 전체 패킷이됩니다 (버퍼가 충분히 큰 경우). the POSIX documentation 가입일

:

가 recvmsg() 함수는 연결 모드 또는 비 접속 모드 소켓으로부터 메시지를 수신한다.

는 "메시지"는 하나의 메시지 (또는 패킷)와 같은 SOCK_DGRAM 및 SOCK_SEQPACKET 같은 메시지 기반 소켓 용

은 전체 메시지가 단일 동작에서 판독한다 정확하게 의미한다.

+0

조각화가있는 경우. ''''recievemsg''는 전체 패킷이 재구성 된 후에 만 ​​데이터를 반환할까요? – Artium

+0

Artium : 예, 이것은 OS에 의해 수행되며 사용자 공간은 조각이 아닌 조립 된 패킷 만 볼 수 있습니다. 이는 수신 된 단편화 된 패킷이 나머지 조각을 기다리는 동안 OS에 의해 보유된다는 것을 의미합니다. –

0

하나의 옵션 (내가 말하는 옵션)은 pcap_next을 사용하여 libpcap을 사용하고 udp 패킷인지 확인합니다. 당신은이 작업을 수행 할 수 있습니다 :

/* jump pass the ethernet header */ 
ipdata = (struct ip*)(packet + sizeof(struct ether_header)); 
length -= sizeof(struct ether_header); 

을 (tcpdump를 빌려) 다음은 UDP 패킷을 수행하여 있는지 확인하기 위해 IP 구조체를 테스트 :

if (ipdata->ip_p == IPPROTO_UDP) 

을 그리고이 실패 할 경우 , udp 패킷을 얻을 때까지 루핑 (pcap_next 호출)을 유지하십시오. 물론, udp 데이터 그램의 추출은 이런 식으로 어렵습니다. 그러나 패킷 내부로 여러분을 아주 멋지게 합칩니다. 정보를 제거하는 방법과 나오는 정보를 보려면 tcpdump 소스를 참조하십시오.

관련 문제