Контекст: я портирую приложение жемчуга Linux на C#, сервер слушает на udp порте и поддерживает несколько параллельных диалоговых окон с удаленными клиентами через единственный сокет udp. Во время тестирования я отсылаю большие объемы пакетов к udp серверу, случайным образом перезапуская клиенты для наблюдения сервера, регистрирующего новые соединения. Проблема - это: когда я уничтожаю udp клиент, могут все еще быть данные по серверу, предназначенному для того клиента. Когда сервер пытается отправить эти данные, это получает icmp "никакой сервис доступное" сообщение назад, и следовательно исключение происходит на сокете.
Я не могу снова использовать этот сокет, когда я пытаюсь связать асинхронный обработчик C# с сокетом, он жалуется на исключение, таким образом, я должен закрыть и вновь открыть сокет udp на порте сервера. Действительно ли это - единственный путь вокруг этой проблемы?, конечно, существует некоторый способ "починить" сокет udp, поскольку технически, сокеты UDP не должны знать о состоянии удаленного сокета?
Любая справка или указатели очень ценились бы.Спасибо.
Я думаю, вы правы, говоря: ' сервер не должен знать ». Если вы отправляете UDP-пакет на какой-то IP / порт, который может быть или не быть открытым, для сервера нет способа узнать, достиг ли он своего места назначения.
Единственный способ узнать об этом сервер - это попросить клиента отправить обратно ACK. (Также и клиент, и сервер должны иметь механизмы повторной отправки в случае потери пакетов).
Очевидно, что что-то еще происходит в вашем коде (или с реализацией udp .Net)
РЕДАКТИРОВАТЬ:
После замечания Николая я проверил документацию. И действительно, в .Net есть различие между «подключением» или «без установления соединения» при использовании UDP.
Если вы используете такой код:
UdpClient udpClient = new UdpClient(11000); //sourceport
try{
udpClient.Connect("www.contoso.com", 11000); //'connect' to destmachine and port
// Sends a message to the host to which you have connected.
Byte[] sendBytes = Encoding.ASCII.GetBytes("Is anybody there?");
udpClient.Send(sendBytes, sendBytes.Length);
, то очевидно, что вы «подключены»
Однако, если вы используете такой код:
UdpClient udpClientB = new UdpClient();
udpClientB.Send(sendBytes, sendBytes.Length, "AlternateHostMachineName", 11000);
, то вы можете отправлять кому угодно без «подключения».
Я не уверен, как выглядит ваш код, но, возможно, стоит проверить, используете ли вы правильный набор команд, который не предполагает «соединение»