Próbowałem swoich sił w obsłudze pakietów i bajtów po raz pierwszy i po wielu różnych technikach nie byłem w stanie poprawnie uzyskać długości pakietu.
Kod:
Public Shared Sub Client(packet As Packet)
Console.WriteLine( _
"Client -> " & _
packet.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff") & _
" length:" & Convert.ToString(packet.Length))
"Define Byte Array
Dim clientPacket As Byte() = packet.Buffer
" Open a Binary Reader
Dim memStream As MemoryStream = New MemoryStream(clientPacket)
Dim bReader As BinaryReader = New BinaryReader(memStream)
" Remove the Ethernet Header
Dim ethBytes As Byte() = bReader.ReadBytes(14)
" Remove the IPv4 Header
Dim IPv4Bytes As Byte() = bReader.ReadBytes(20)
" Remove the TCP Header
Dim TCPBytes As Byte() = bReader.ReadBytes(20)
" Get the packet length
If clientPacket.Length > 54 Then
Dim len As UInt32 = bReader.ReadUInt32
Console.WriteLine(len)
End If
End Sub
Do tej pory wszystkie moje próby posiadania konsolizapisz długość danych spowodowało błąd. Zweryfikowałem endianness i faktycznie wypisałem bajty, aby sprawdzić, czy przetwarzałem prawidłowe dane.
Przykładowe bajty:
00 00 00 24 -> UINT32 ma 36 bajtów, ale otrzymuję tablicę liczb całkowitych takich jak 3808493568
Jak mogę to naprawić?
Odpowiedzi:
1 dla odpowiedzi № 1Zgadzam się z Hansem, endianizm jest twoim problemem. Ponadto polecam korzystanie z BitConverter
klasa na clientPacket
tablica, łatwiejsze niż korzystanie ze strumieni.
Dim len As UInt32
Dim arr() As Byte
arr = {0, 0, 0, 24}
len = BitConverter.ToUInt32(arr, 0)
Console.Write(len.ToString) "returns 402653184
arr = {24, 0, 0, 0}
len = BitConverter.ToUInt32(arr, 0)
Console.Write(len.ToString) "returns 24
W przypadku twojego kodu myślę, że może to działać (niesprawdzone):
If clientPacket.Length > 54 Then
Dim lenBytes As Byte() = bReader.ReadBytes(4)
Array.Reverse(lenBytes, 0, 4)
Dim len As UInt32 = BitConverter.ToUInt32(lenBytes, 0)