Я работаю над консольным приложением, которому необходимо получать данные от двух локальных конечных точек и впоследствии отправлять эти данные на две удаленные конечные точки - параллельно. У меня есть код для получения/отправки данных в задаче, который выглядит следующим образом:
public async Task RecvAndSend(DataObj data, bool isRequest)
{
try
{
using var recv = new UdpClient(data.localPort);
using var send = new UdpClient();
var remoteEndpoint = new IPEndPoint(data.remoteAddress, data.remotePort);
while (true)
{
try
{
byte[] res = (await recv.ReceiveAsync()).Buffer;
await send.SendAsync(res, res.Length, remoteEndpoint);
Console.Write(isRequest ? "-" : "~");
}
catch (Exception ex) {
Console.WriteLine("Exception thrown in while loop: {0}", ex.Message);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Эта задача принимает 2 параметра. Первыми являются данные, относящиеся к локальному порту, на который эта задача будет получать данные, и удаленному адресу, на который она будет пересылать эти данные.
Как я уже упоминал, два экземпляра этой задачи должны выполняться параллельно. Один экземпляр называется задачей «Запрос», а другой — задачей «Ответ». Я передаю логическое значение (isRequest), которое можно использовать для записи символа в консоль для любой задачи, только что завершившей итерацию цикла while.
Я начинаю эти параллельные задачи следующим образом:
Task t1 = RecvAndSend(requestData, true);
Task t2 = RecvAndSend(responseData, false);
await Task.WhenAll(t1, t2);
Проблема в том, что первая задача начнет получать/отправлять данные, но как только вторая задача начнет получать/отправлять данные, первая задача останавливается. Итак, мой вывод выглядит примерно так:
-------~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Я ожидаю увидеть следующее:
-~-~-~-~-~-~
Возможно, это не так синхронно, но вы поняли.
Я пробовал создавать отдельные UdpClients для отправки и получения внутри каждой задачи, а также пробовал объявлять глобальные клиенты, предназначенные для получения/отправки, и использовать механизм блокировки внутри задачи.
Ничто не сработало так, как ожидалось. На данный момент я не уверен, возможно ли вообще иметь 2 потока с двумя UdpClient, каждый из которых получает и отправляет одновременно.
@Charlieface Нет, я выделяю отдельные порты для каждого клиента.
Для начала — выньте блоки try/catch и посмотрите, какую информацию вам выдает отладчик.
@Enigmativity Удалены блоки try/catch, и от отладчика ничего не получено. Все еще вижу, что моя первая задача приема/отправки останавливается после запуска второй. Я установил точку останова для своей первой задачи и увидел, что свойство UdpClient.Active имеет значение false после запуска второй.





Я смог решить эту проблему. Моя проблема оказалась связана с номером порта. Я создавал отдельный клиент для отправки данных, которые были привязаны к случайному доступному порту, выбранному ОС. Получив эти данные, сервер назначения начал отвечать на этот случайный порт, а не на порт, с которого он первоначально начал отправлять данные. По этой причине мой принимающий клиент остановился как вкопанный. Через порт, от которого он ожидал данные, больше не поступали данные.
Они используют одни и те же номера локальных портов?