在 C# 中通过数据包发送十六进制值

发布于 2024-12-05 09:28:38 字数 203 浏览 0 评论 0原文

我目前有以下问题:

N.Sockets.UdpClient UD;

UD = new N.Sockets.UdpClient();
UD.Connect("xxx.xxx.xxx.xxx", 5255);
UD.Send( data, data.Length );

如何以十六进制发送数据?我不能直接将其保存到字节数组中。

I currently have the following:

N.Sockets.UdpClient UD;

UD = new N.Sockets.UdpClient();
UD.Connect("xxx.xxx.xxx.xxx", 5255);
UD.Send( data, data.Length );

How would I send data in hex? I cannot just save it straight into a Byte array.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

止于盛夏 2024-12-12 09:28:38

十六进制只是一种编码。它只是表示数字的一种方式。计算机仅处理位和字节——它没有“十六进制”的概念。

因此,任何数字,无论是十六进制、十进制还是二进制表示,都可以编码为一系列字节:

var data = new byte[] { 0xFF };

并且任何十六进制字符串都可以转换为数字(例如使用int.Parse())。

当数字超过一个字节时,事情会变得更有趣:然后必须就使用多少字节来表示该数字以及它们应该采用的顺序达成一致。

在 C# 中,ints是4个字节。在内部,根据 CPU 的字节序,最高有效字节(最高值的数字)可能会首先存储(大端)或最后存储(小端)。通常,大端字节序用作网络通信的标准(请记住,发送方和接收方可能拥有具有不同字节序的 CPU)。但是,由于您手动发送原始字节,我假设您也在另一端手动读取原始字节;如果是这样的话,您当然可以自由地使用您喜欢的任何任意格式,前提是客户可以明确地理解该格式。

要以大端顺序对 int 进行编码,您可以执行以下操作:

int num = 0xdeadbeef;
var unum = (uint)num;    // Convert to uint for correct >> with negative numbers
var data = new[] {
    (byte)(unum >> 24),
    (byte)(unum >> 16),
    (byte)(unum >> 8),
    (byte)(unum)
};

请注意,某些数据包可能永远不会到达客户端(这是 TCP 和 UDP 之间的主要实际差异),可能会导致对字节。您应该采取措施提高消息发送的稳健性(例如,通过添加校验和,并忽略校验和无效或丢失的值)。

Hex is just an encoding. It's simply a way of representing a number. The computer works with bits and bytes only -- it has no notion of "hex".

So any number, whether represented in hex or decimal or binary, can be encoded into a series of bytes:

var data = new byte[] { 0xFF };

And any hex string can be converted into a number (using, e.g. int.Parse()).

Things get more interesting when a number exceeds one byte: Then there has to be an agreement of how many bytes will be used to represent the number, and the order they should be in.

In C#, ints are 4 bytes. Internally, depending on the endianness of the CPU, the most significant byte (highest-valued digits) might be stored first (big-endian) or last (little-endian). Typically, big-endian is used as the standard for communication over the network (remember the sender and receiver might have CPUs with different endianness). But, since you are sending the raw bytes manually, I'll assume you are also reading the raw bytes manually on the other end; if that's the case, you are of course free to use any arbitrary format you like, providing that the client can understand that format unambiguously.

To encode an int in big-endian order, you can do:

int num = 0xdeadbeef;
var unum = (uint)num;    // Convert to uint for correct >> with negative numbers
var data = new[] {
    (byte)(unum >> 24),
    (byte)(unum >> 16),
    (byte)(unum >> 8),
    (byte)(unum)
};

Be aware that some packets might never reach the client (this is the main practical difference between TCP and UDP), possibly leading to misinterpretation of the bytes. You should take steps to improve the robustness of your message-sending (e.g. by adding a checksum, and ignoring values whose checksums are invalid or missing).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文