String 无法附加到UDP侦听器C中接收的字符串#

String 无法附加到UDP侦听器C中接收的字符串#,string,multithreading,asynchronous,udp,beginreceive,String,Multithreading,Asynchronous,Udp,Beginreceive,我有一个创建UDP对象的表单,在UDP类中创建一个UDPClient,并使用EndReceive在BeginReceive方法中完成接收数据 在转换字节[]后,当我从beginreceive方法中向控制台打印已接收数据的字符串并附加文本时,只有接收到的数据不会打印附加文本 所以看起来接收到的数据是不完整的 打印字符串时,不显示换行符和附加的“完成” 任何帮助都会很好 谢谢 class Udp { public EventHandler _dataReceived; public

我有一个创建UDP对象的表单,在UDP类中创建一个UDPClient,并使用EndReceive在BeginReceive方法中完成接收数据

在转换字节[]后,当我从beginreceive方法中向控制台打印已接收数据的字符串并附加文本时,只有接收到的数据不会打印附加文本

所以看起来接收到的数据是不完整的

打印字符串时,不显示换行符和附加的“完成”

任何帮助都会很好

谢谢

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);
}

    }    
class-Udp
{
公共事件处理程序(public EventHandler)接收到数据;;
公共Udp()
{
int receiverPort=1248;
UdpClient receiver=新的UdpClient(receiverPort);
字符串发现=”;
receiver.BeginReceive(新的异步回调(DataReceived),receiver);
IPEndPoint end=新的IPEndPoint(IPAddress.Broadcast,1248);
receiver.Send(Encoding.ASCII.GetBytes(discovery+“\0”)、discovery.Length+1、end);
}
接收到私有无效数据(IAsyncResult ar)
{
UdpClient c=(UdpClient)ar.AsyncState;
IPEndPoint receivedIpEndPoint=新IPEndPoint(IPAddress.Any,1248);
字节[]receivedBytes=c.EndReceive(ar,ref receivedIpEndPoint);
string receivedText=ascienceoding.ASCII.GetString(receivedBytes);
Console.WriteLine(“\n”);
如果(_dataReceived!=null)
{
Console.Write(receivedIpEndPoint+“:”+receivedText+Environment.NewLine+“done”);
_dataReceived(receivedText,new EventArgs());
}
c、 BeginReceive(新异步回调(DataReceived),c);
}
}    

我能想到的解决这个问题的最简单的方法是以下代码:

    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字节的存在导致输出字符串被截断。超出该字节的内容不会进入VisualStudio输出窗口

要解释这种行为,需要深入了解Winforms应用程序中Console.Write()的工作原理以及它如何生成输出,即使您的程序没有控制台。这是一个长篇大论的故事,不太可能让任何人开心,所以我将用短篇的版本。启用Visual Studio宿主进程调试器选项后,Console.Write()相当于Debug.Write()。调试输出被DefaultTraceListener类截获,它会使文本显示在调试器跟踪窗口中。这些winapi函数接受C字符串,C字符串以零结尾以指示字符串的结尾

有几种方法可以解决此问题,程序员的方法是将byte[]数组内容转换为十六进制:

    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

或者,您可能希望更好地查看传输的数据,确保它实际上是可打印的文本,可以通过编码进行正确转换。ASCII

至少需要一个小样本和源代码。我在中编辑了一些源代码,如前所述。换行符和“完成”不打印您是否尝试使用Stringbuilder类而不是字符串?@Robert:您应该接受一个答案,或者添加一条注释,说明为什么答案不能解决问题。