【问题标题】:C# - Bytes converting doesn't not work as it shouldC# - 字节转换不起作用
【发布时间】:2016-11-16 18:21:37
【问题描述】:

我正在使用 Source RCON 协议,但在将字符串成功转换为字节数组时遇到问题。

原码(VB.NET)+Pastebin:http://pastebin.com/4BkbTRfD

Private Function RCON_Command(ByVal Command As String, 
                              ByVal ServerData As Integer) As Byte()
     Dim Packet As Byte() = New Byte(CByte((13 + Command.Length))) {}
     Packet(0) = Command.Length + 9    'Packet Size (Integer)
     Packet(4) = 0                     'Request Id (Integer)
     Packet(8) = ServerData            'SERVERDATA_EXECCOMMAND / SERVERDATA_AUTH (Integer)
     For X As Integer = 0 To Command.Length - 1
         Packet(12 + X) = System.Text.Encoding.Default.GetBytes(Command(X))(0)
     Next
     Return Packet
End Function

我目前在 C# + Pastebin 中的代码:http://pastebin.com/eVv0nZCf

byte[] RCONCommand(string cmd, int serverData)
{
    int packetSize = cmd.Length + 12;
    byte[] byteList = new byte[packetSize];
    byteList[0] = (byte)packetSize;
    byteList[4] = 0;
    byteList[8] = (byte)serverData;

    for(int X = 0; X < cmd.Length; X++)
    {
        byteList[12 + X] = Encoding.ASCII.GetBytes(cmd)[X];
    }

    return byteList;
}

当我使用 Encoding.ASCII.GetString(RCONCommand("Word", 3));结果将是方形标记。我也尝试过 Encoding.UTF8.GetString(),但结果相同。

数据包结构可以在这里找到:https://developer.valvesoftware.com/wiki/Source_RCON_Protocol#Basic_Packet_Structure

我不只是弄清楚我做错了什么,因为我什至不熟悉字节等。 PS。已在 C# 中发布的用于 Source RCON 协议文档的示例应用程序是乱码,因为人们使用了如此多的 OOP 并创建了数百万个类文件,所以我什至找不到正确的东西。

【问题讨论】:

    标签: c# vb.net tcp byte packet


    【解决方案1】:

    一个字节是 8 位。这意味着像 Size 这样的值,根据规范是一个 32 位小端无符号整数,需要 4 个字节 (32 ÷ 8 = 4)。

    要将 32 位信息放入四个字节,您必须将其拆分。可以将其视为将一个四位数字分成四个字符串,每个数字一个。除了我们在二进制中工作,所以它有点复杂。我们必须做一些位移和掩码才能将我们想要的位放入每个“字符串”中。

    规范要求little-endian,因此最低有效字节排在第一位;如果您以前没有这样做过,这需要一些时间来适应。

    byte[0] = size && 0xFF;
    byte[1] = (size >> 8) && 0xFF;
    byte[2] = (size >> 16) && 0xFF;
    byte[3] = (size >> 24) && 0xFF;
    

    如果你想依赖 CLR,你可以使用BitConverter,虽然它依赖于平台,而且不是所有的平台都是 little-endian。

    var tmp = BitConverter.GetBytes(size);
    if (BitConverter.IsLittleEndian)
    {
        byte[0] = tmp[0];
        byte[1] = tmp[1];
        byte[2] = tmp[2];
        byte[3] = tmp[3];
    }
    else  //in case you are running on a bigendian machine like a Mac
    {
        byte[0] = tmp[3];
        byte[1] = tmp[2];
        byte[2] = tmp[1];
        byte[3] = tmp[0];
    }
    

    【讨论】:

    • IPAddress.HostToNetworkOrder(size) 可以更简单一点
    猜你喜欢
    • 2012-04-28
    • 1970-01-01
    • 2013-02-18
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多