Страницы

Поиск по вопросам

среда, 22 января 2020 г.

C# UDP Отправка сервера к клиенту байт выдает ошибку

#c_sharp #сеть #udp


Всем привет! Когда сервер отправляет байт данных на уже отключенный клиент то я получаю
вот такое исключение:



Kак узнать клиент доступен ли?
Как утсранить эту проблему или обоити
?

Искал в интернете, нашел пару похожих вопросов но у них другие проблемы в конце решил
спросить тут.

Server:

        byte[] buffer = new byte[1024];
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 23000);
        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        EndPoint EP = (EndPoint)sender;

        int i;
        sock.Bind(ipep);

        while (true)
        {
            try
            {
                i = sock.ReceiveFrom(buffer, ref EP); // ошибка появляется здесь
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                Console.ReadKey();
                break;
            }

            // нажимаем на любую клаву чтобы получить ошибку
            Console.WriteLine("Нажмите любую клавишу чтобы отправить байт клиенту
и получить ошибку");
            Console.ReadKey();
            sock.SendTo(buffer, i, SocketFlags.None, EP);


Client:

        int serverPort = 23000;
        string hostName = "127.0.0.1";
        byte[] buffer = new byte[1024];

        EndPoint remote;
        IPEndPoint endPoint;
        Socket server;

        endPoint = new IPEndPoint(IPAddress.Parse(hostName), serverPort);
        server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

        remote = (EndPoint)sender;

        buffer = Encoding.Unicode.GetBytes("me send");
        server.SendTo(buffer, 0, buffer.Length, SocketFlags.None, endPoint);

        // выходим из клиента чтобы сервер отправил отключенному клиенту;

    


Ответы

Ответ 1



Socket.ReceiveFrom внутри использует функцию recvfrom. Она соотвественно может завершится с ошибкой WSAECONNRESET(код у неё 10054). В документации на функцию recvfrom указанано следующие описание ошибки WSAECONNRESET: The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket; it is no longer usable. On a UDP-datagram socket this error indicates a previous send operation resulted in an ICMP Port Unreachable message. В кратце на русском: Если хост разорвет соединение и после этого будет вызыван send, то последующая операция чтения завершится с этой ошибкой. Соответственно чтобы решить вашу проблему, нужно использовать примерно такой код: static void Main(string[] args) { using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { byte[] buffer = new byte[1024]; socket.Bind(new IPEndPoint(IPAddress.Any, 23000)); while (true) { var i = 0; EndPoint clientPoint = new IPEndPoint(IPAddress.Any, 0); try { i = socket.ReceiveFrom(buffer, ref clientPoint); } catch (SocketException ex) when (ex.ErrorCode == 10054) { // ни чего не делаем идем дальше continue; } catch (Exception ex) { Console.WriteLine(ex.ToString()); break; } socket.SendTo(buffer, i, SocketFlags.None, clientPoint); } } } PS: Есть еще магическая константа SIO_UDP_CONNRESET, которая вроде убирает генерирование этой ошибки. Но я не уверен, что она влияет только на этот случай поэтому код приводить с ней не буду.

Комментариев нет:

Отправить комментарий