6

UDP オブジェクトを作成するフォームがあり、UDP クラスで UDPClient が作成され、受信データは EndReceive を使用して BeginReceive メソッドで処理されます。

byte[] を変換した後、受信したデータの文字列を beginreceive メソッド内からテキストを追加してコンソールに出力すると、受信したデータのみが出力され、追加されたテキストは出力されません。

そのため、受信したデータが不完全なようです。

文字列が印刷されるとき、NewLine と追加された「done」は表示されません。

どんな助けでも素晴らしいでしょう!!

ありがとう

class Udp
{
    public EventHandler _dataReceived;

    public Udp()
    {

        int receiverPort = 1248;
        UdpClient receiver = new UdpClient(receiverPort);

        string discovery = "<?xml version=\"1.0\"?><ServiceQuery></ServiceQuery>";

        receiver.BeginReceive(new AsyncCallback( DataReceived), receiver);

        IPEndPoint end = new IPEndPoint(IPAddress.Broadcast, 1248);
        receiver.Send(Encoding.ASCII.GetBytes(discovery + "\0"), discovery.Length + 1, end);
}

private void DataReceived(IAsyncResult ar)
{
    UdpClient c = (UdpClient)ar.AsyncState;
    IPEndPoint receivedIpEndPoint = new IPEndPoint(IPAddress.Any, 1248);

    Byte[] receivedBytes = c.EndReceive(ar, ref receivedIpEndPoint);

    string receivedText = ASCIIEncoding.ASCII.GetString(receivedBytes);

    Console.WriteLine("\n");

    if(_dataReceived != null)
    {
        Console.Write(receivedIpEndPoint + ": " + receivedText + Environment.NewLine + "done");
       _dataReceived(receivedText, new EventArgs());
    }

    c.BeginReceive(new AsyncCallback(DataReceived), c);
}

    }    
4

1 に答える 1

4

この問題に対して私が考えることができる最も単純な再現は、次のコードです。

    private void button1_Click(object sender, EventArgs e) {
        Byte[] receivedBytes = new byte[] { 0x48, 0x65, 0x6c, 0x00, 0x6c, 0x6f };
        string receivedText = Encoding.ASCII.GetString(receivedBytes);
        Console.Write(receivedText + ", you won't see this");
    }

ボタンを数回クリックした後の出力:

   HelHelHelHel

これで、 receivedBytes配列にポイズン ピルが含まれていることがわかります。これは、出力文字列が短くなる原因となる 0x00 バイトの存在です。そのバイトを超えるものは、Visual Studio の [出力] ウィンドウには表示されません。

この動作を説明するには、プログラムにコンソールがない場合でも、Winform アプリで Console.Write() がどのように機能し、どのように出力を生成できるかについて、かなり深く掘り下げる必要があります。これは長々とした話で、誰も楽しませる可能性は低いので、短いバージョンをお勧めします. Visual Studio Hosting Process デバッガー オプションを有効にすると、Console.Write() は Debug.Write() と同等になります。デバッグ出力は DefaultTraceListener クラスによってインターセプトされ、OutputDebugString()をピン呼び出しして、デバッガー トレース ウィンドウに表示されるテキストを取得します。これらの winapi 関数は C 文字列を受け取ります。C 文字列は、文字列の終わりを示すためにゼロで終了します。

これを修正するにはいくつかの方法があります。プログラマーの方法は、byte[] 配列の内容を 16 進数に変換することです。

    Byte[] receivedBytes = new byte[] { 0x48, 0x65, 0x6c, 0x00, 0x6c, 0x6f };
    string receivedText = BitConverter.ToString(receivedBytes);
    Console.WriteLine(receivedText + ", you see this");

出力:

    48-65-6C-00-6C-6F, you see this
    48-65-6C-00-6C-6F, you see this
    48-65-6C-00-6C-6F, you see this

または、送信するデータをよく見て、Encoding.ASCII で適切に変換できる実際に印刷可能なテキストであることを確認することもできます。

于 2015-08-01T14:35:34.750 に答える