2013-08-26 5 views
0

udp 원시 소켓을 사용하고 있습니다.C# raw socket ip header 총 길이

모든 패킷의 첫 번째 예를 들어, 64 바이트 만 읽으려고합니다.

ipaddr = IPAddress.Parse("10.1.2.3"); 

sock = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP); 
sock.Bind(new IPEndPoint(ipaddr, 0)); 
sock.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true); 
sock.IOControl(IOControlCode.ReceiveAll, BitConverter.GetBytes(RCVALL_IPLEVEL), null); 
sock.ReceiveBufferSize = 32768; 

byte[] buffer = new byte[64]; // max IP header, plus tcp/udp ports 
while (!bTheEnd) 
{ 
    int ret = sock.Receive(buffer, buffer.Length, SocketFlags.None); 
    ... 
} 

는 I는 패킷을 수신하지만, IP 헤더 ' "전장"모든 < = 64

I 더 큰 버퍼를 사용하는 경우 (바이트 [완충액 = 새로운 바이트 [32768]), I 오른쪽 총계 길이를 얻었습니다 (현재 값은 < = 32768).

목표는 모든 패킷, IP 헤더 및 해당 패킷 길이를 얻는 것입니다. 루틴이 tcp/ip 스택에 패킷 단편화를 일으킬 필요가 없습니다.

+0

목표는 각 패킷의 처음 64 바이트 만 읽는 것입니다. SocketFlags.Peek를 사용하면 다음 패킷으로 전달하는 방법을 모르겠습니다. SocketFlags.None 함께 첫 번째 바이트 만 읽지 못했습니다. 완벽한 패킷을 읽는 것이 내 목표는 아닙니다. – Massimo

+0

sock.DontFragment = true; 및 sock.Receive (..., SocketFlags.Partial); 도움이되지 않는다. 나는 뭔가를 놓치고 있다고 느낍니다. – Massimo

답변

1

SocketFlags.Peek은 반환 된 데이터가 이후 읽기를 위해 그대로 유지된다는 것을 의미하므로 다시 읽은 후 동일한 데이터를 얻습니다. 후속 패킷을 읽으려면 Peek를 사용하지 않으려면 특수 플래그없이 일반 읽기를 수행하면됩니다.

는 수신 데이터 그램 버퍼 매개 변수의 크기보다 큰 경우, 버퍼가 메시지의 첫 번째 부분으로 채워집니다

의 초과 데이터가 손실되고 SocketException이 : 문서에 따르면

던졌습니다.

그 행동이 나았습니까?

+0

Jacek, 당신은 바로 문서에 대한 것입니다. 작은 버퍼를 사용하여, 나는 패킷의 헤더와 SocketException을 얻는다. 그러나 IP 헤더 필드 "total length"는 항상 내 버퍼 길이보다 작습니다! 패킷을 잃어버린 것 같아요, 아니면 winsock API가 버퍼 크기를 존중하기 위해 패킷을 조각 내고 있습니까? – Massimo

+0

몇 달 전 winpcap을 사용하고 있으며 동일한 작업이 정상적으로 수행되었습니다. 난 머리글과 올바른 "총 길이"필드를 캡처 할 수 있습니다. – Massimo

+0

나머지 패킷을 삭제하려는 동기는 정확히 무엇입니까? 전체 패킷을 읽고 필요없는 것을 버리는 것이 왜 좋지 않은가요? –