Не удается добавить к полученной строке в слушателе 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.