以正确的字节顺序发送UDP数据包

以正确的字节顺序发送UDP数据包

问题描述:

嗨,大家好我无法理解网络字节顺序以及通过UDP发送和接收数据的顺序。我使用C#以正确的字节顺序发送UDP数据包

我有一个结构,控股:使用

message.start_id   = 0x7777CCCC; 
message.message _id  = 0xBBB67000; 
    more data 

消息定义具有[StructLayout(LayoutKind.Sequential)]

我第一次结构转换为字节数组:

public byte[] StructureToByteArray(object obj) 
{ 
    int len = Marshal.SizeOf(obj); 
    byte[] arr = new byte[len]; 
    IntPtr ptr = Marshal.AllocHGlobal(len); 
    Marshal.StructureToPtr(obj, ptr, true); 
    Marshal.Copy(ptr, arr, 0, len); 
    Marshal.FreeHGlobal(ptr); 
    return arr; 
} 

而且然后我检查字节顺序:

if (BitConverter.IsLittleEndian) 
{ 
    Array.Reverse(packet); 
} 

然后我发送

socket.SendTo(packet, endPoint); 

当我发送此接收端接收与应用了正确的字节顺序,但以相反的顺序的字节的报文,所以期待在Wireshark的我得到:

其余部分。 ................. BBB67000 7777CCCC

当我期待:7777CCCC BBB67000 ...................其余的

是我期待的权利或是正常的第一个字节在st是最后到达的吗?

非常感谢

+2

Endianness不应该应用于整个数据包 - 它应该应用在各个部分上......我认为这是每32位完成一次,但我不是100%。 –

+1

几乎是Michael Bray所说的。字节顺序被应用于各个部分(对于'start_id'和'message_id'分别是这样),它在字节级别(所以在一个4字节的int中,第一个字节与第四个字节交换,第二个字节与3rd) – xanatos

我无法理解网络字节顺序,并在数据的发送和通过UDP收到

数据以完全字节发送和接收通过UDP的顺序订单给予套接字。您只发送或接收字节数组,而UDP根本不重新排序数据报中的字节。

那么问题是,如何处理字节序?

那么,在很多情况下,答案是“没有”。首先,你今天遇到的大多数计算机都运行x86架构,并且总是使用小端。而且在很多情况下,无论如何您都可以控制两端,因此可以始终坚持一个或另一个。如果你的API有一种方法可以将字节流转换成字节流,你可以直接使用UDP套接字发送和接收这些字节。

但是,有时您需要能够处理传输数据的字节顺序,这与您程序运行的体系结构本机支持的数据不同。

在你特别的例子中,你似乎选择了使用big-endian作为你的协议的字节顺序(我从一点点的代码推断这一点;当然,如果没有a good Minimal, Complete, and Verifiable example肯定不知道) 。这很好;原始的BSD套接字API包含了“网络字节顺序”的概念,这是大端的。套接字库包括转换的功能,例如,从“主机顺序”到“网络顺序”并返回的16位整数。

但重要的是要明白,字节序会影响数据中每个单独基元级别的数据。你不能一次反转整个字节数组,因为如果你这样做,不仅会改变每个单独基元的字节顺序,还会改变基元本身的顺序。当然,你可以在你的Wireshark跟踪中看到:数据结构中的两个字段已经交换了它们的顺序。

要正确处理字节顺序,必须遍历数据结构的每个字段并单独交换字节。 值(16位)将会有它们的一对字节交换,int值(32位)会将它们的四字节序列反转,long值(64位)将会有八个字节反转,依此类推。为了使事情更加复杂,一些数据结构根本不受字节顺序的影响(例如UTF8编码的文本),而其他的则有更复杂的规则(例如Windows GUID/UUID,它是一个128位的值这实际上被定义为一个复杂的数据结构,具有不同大小的多个字段)。

要记住的重要一点是,考虑到基本数据值使用的实际字节数,字节序总是应用于每个单独基本数据值的级别。

+0

嗨Peter, 非常感谢您的回复。我看了一下MS提供的各种函数(htonl等),但找不到任何东西,uint,双打等等。我在需要发送的结构中混合了所有的东西。因为所有的值都是32位,所以我通过在一次的时间内遍历结构1字节手动交换字节结构中的字节,复制到一个新的字节,执行一个数组。反转并将其复制到一个相同大小的新字节结构中。我已经在电线上测试过它,它似乎工作:\。非常感谢。 – moonraker