1

この 16 進パケットを送信したい:

00 38 60 dc 00 00 04 33  30 3c 00 00 00 20 63 62 
39 62 33 61 36 37 34 64  31 36 66 32 31 39 30 64 
30 34 30 63 30 39 32 66  34 66 38 38 32 62 00 06 
35 2e 31 33 2e 31 00 00  02 3c

だから私は文字列を構築します:

string packet = "003860dc0000" + textbox1.text+ "00000020" + textbox2.text+ "0006" + textbox3.text;

それを ascii に「変換」します。

conn_str = HexString2Ascii(packet);

それから私はパケットを送信します...しかし、私はこれを持っています:

00 38 60 **c3 9c** 00 00 04 33  30 3c 00 00 00 20 63 
62 39 62 33 61 36 37 34 64  31 36 66 32 31 39 30 
64 30 34 30 63 30 39 32 66  34 66 38 38 32 62 00 
06 35 2e 31 33 2e 31 00 00  02 3c **0a**

どうして??ありがとうございました!PS関数は次のとおりです。

private string HexString2Ascii(string hexString)
{
     byte[] tmp;
     int j = 0;
     int lenght;
     lenght=hexString.Length-2;
     tmp = new byte[(hexString.Length)/2];
     for (int i = 0; i <= lenght; i += 2)
     {
         tmp[j] =(byte)Convert.ToChar(Int32.Parse(hexString.Substring(i, 2), System.Globalization.NumberStyles.HexNumber));
         j++;
     }
     return Encoding.GetEncoding(1252).GetString(tmp);
}

編集:バイトに直接変換すると、文字列としてコード化された16進パケット:

00000000  30 30 33 38 36 30 64 63  30 30 30 30 30 34 33 33 003860dc 00000433
00000010  33 30 33 43 30 30 30 30  30 30 32 30 33 34 33 32 303C0000 00203432
00000020  36 33 36 33 33 35 33 39  33 32 33 34 36 36 33 39 63633539 32346639
00000030  36 33 33 39 33 31 33 39  33 30 33 36 33 33 36 35 63393139 30363365
00000040  33 35 36 33 36 35 36 35  36 35 33 31 33 39 33 38 35636565 65313938
00000050  36 33 33 31 36 34 33 34  36 33 33 30 30 30 30 36 63316434 63300006
00000060  33 35 32 65 33 31 33 33  32 65 33 31 30 30 30 30 352e3133 2e310000
00000070  30 32 33 43                                      023C
4

1 に答える 1

2

生のバイナリ データを文字列データに変換して、そのまま動作することを期待することはできません。それらは同じではありません。これは、文字エンコーディングを混同した場合に特に当てはまります。

C# 文字は ASCII 文字ではありません。これらは、Unicode コード ポイントで表される Unicode 文字です。ひっくり返してそれらの文字を書き出すときは、どのようなデータを書き出すかを指定する必要があります。Encoding.GetEncoding(1252) を使用してバイト配列を文字列に読み込むと、コード ページ 1252 に対応する文字が取得され0xdcますÜ

ただし、文字列がネットワーク経由で送信するためにバイトに変換されると、UTF-8 として書き出されます。UTF-8 では、UTF-00DC を 1 バイトとしてエンコードすることはできません。これは、そのバイト値がマルチバイト シーケンスの開始を示すために使用されるためです。代わりに、マルチバイト シーケンスとしてエンコードされます0xc3 0x9c。C# に関する限り、これら 2 つの値は同じ文字です。(その余分な 0x0a がどこから来ているのかはわかりませんが、私の推測では、テキスト ボックスの 1 つおよび/またはプロセスの他の部分からの誤った改行です)。

正確に何をしようとしているのかは明確ではありませんが、正しく機能するにはあまりにも多くの変換を行っているのではないかと思います。送信したいバイト シーケンスがわかっている場合は、それを byte[] として直接エンコードしてみませんか? たとえば、 a を使用して、MemoryStream必要な定数バイトを書き込みます。

テキスト ボックスから値を取得するために、16 進数の文字列を ASCII 文字の文字列に "変換" する元のコードには正しい考えがありました。最終的にはバイト配列が必要になるため、バイト配列がある時点で停止する必要があります

public byte[] GetBytesFrom(string hex)
{
    var length = hex.Length / 2;
    var result = new byte[length];
    for (var i = 0; i < length; i++)
    {          
      result[i] = byte.Parse(hex.Substring(i, 2), NumberStyles.HexNumber);
    }

    return result;
}

// Variable portions of packet structure.
var byte[] segment2 = GetBytesFrom(textbox1.Text);
var byte[] segment4 = GetBytesFrom(textbox2.Text);
var byte[] segment6 = GetBytesFrom(textbox3.Text);

MemoryStream output = new MemoryStream();
output.Write(new[] { 0x00, 0x38, 0x60, 0xdc, 0x00, 0x00 }, 0, 6);
output.Write(segment2, 0, segment2.Length);
output.Write(new[] { 0x00, 0x00, 0x00, 0x20 }, 0, 4);
output.Write(segment4, 0, segment4.Length);
output.Write(new[] { 0x00, 0x06 }, 0, 2);
output.Write(segment6, 0, segment6.Length);

ここから、MemoryStream.CopyTo()それを別のストリームにコピーしたりMemoryStream.Read()、パケット全体を新しいバイト配列に読み取ったりMemoryStream.GetBuffer()、基礎となるバッファーを取得したりするために使用できます (最後のバッファーが必要になることはめったにありませんが、未使用のパディング バイトが含まれています)。

于 2012-06-24T22:17:39.113 に答える