Не удается добавить к полученной строке в слушателе UDP C#

У меня есть форма, которая создает объект UDP, в классе UDP создается клиент UDPClient, а полученные данные обрабатываются с помощью метода BeginReceive с помощью EndReceive.

Когда я печатаю строку восстановленных данных, после преобразования байта [] в консоль из метода 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);
}

    }    

1 ответ

Самое простое повторение, которое я могу придумать для этой проблемы, - это код:

    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

Конечно, теперь вы узнаете яд-таблетку в массиве receiveBytes, именно наличие байта 0x00 приводит к короткому замыканию выходной строки. Ничто, кроме этого байта, не попадает в окно вывода Visual Studio.

Для объяснения этого поведения требуется довольно глубокое погружение в то, как работает Console.Write() в приложении Winforms и как оно способно генерировать вывод, даже если ваша программа не имеет консоли. Это длинная история, которая вряд ли кого-нибудь развлечет, так что я буду в поисках короткой версии. При включенной опции отладчика процесса хостинга Visual Studio Console.Write() эквивалентна Debug.Write(). Вывод отладочной информации перехватывается классом DefaultTraceListener, он выводит OutputDebugString(), чтобы текст отображался в окне трассировки отладчика. Эти функции winapi принимают строки C, строка C заканчивается нулем, чтобы указать конец строки.

Есть несколько способов исправить это, способ программиста состоит в том, чтобы преобразовать содержимое массива byte[] в hex:

    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.

Другие вопросы по тегам