2016-11-16 5 views
0

ソースRCONプロトコルで再生していますが、文字列をバイト配列に変換する際に問題があります。C# - バイト変換が正常に動作しない

オリジナルコード(VB.NET)+ペーストビン: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#+ペーストビンで私の現在のコード: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を(」を使用単語 "、3));結果は四角いマークになります。 Encoding.UTF8.GetString()も試しましたが、同じ結果が得られました。

パケット構造は、ここで見つけることができます:https://developer.valvesoftware.com/wiki/Source_RCON_Protocol#Basic_Packet_Structure

私もバイトに精通し、そのようじゃないので、私はちょうど、私が間違って何をやったか、それを把握していません。 PS。人々は非常に多くのOOPを使用しており、何百万ものクラスファイルを作成しているため、正しいものを見つけることさえできないため、ソースRCONプロトコルのドキュメント用にC#で公開されているサンプルアプリケーションは文字化けしています。

答えて

1

バイトは8ビットです。これは、仕様によると、32ビットのリトルエンディアンの符号なし整数であるSizeのような値は、4バイト(32÷8 = 4)を必要とすることを意味します。

32ビットの情報を4バイトに収めるには、分割する必要があります。これは、4桁の数字を1桁ごとに4桁に分割すると考えてください。私たちはバイナリで作業していることを除いて、もう少し複雑です。私たちはそれぞれの "文字列"に必要なビットだけを得るためにビットシフトとマスキングを行う必要があります。

この仕様では、little-endianが必要です。最下位バイトが最初に来ます。以前にこれをやっていないのであれば、これは慣れています。

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

あなたはCLRに依存する場合、それはプラットフォームに依存しますが、あなたは、BitConverterを使用することができ、およびすべてのプラットフォームは、リトルエンディアンわけではありません。

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]; 
} 
+0

'IPAddress.HostToNetworkOrder(size)'は、より簡単に少し入札できます – Fabio

関連する問題