C# UDP通信 ReceiveAsync() 一直等待问题

问题描述

两个C#应用,一个作为服务端Server,另一个作为客户端Client,客户端打开一个Udp端口,循环接收数据;服务端开启后向客户端发送指令,当服务端出现异常时关闭了服务端的UdpClient,此时客户端卡死在_client.ReceiveAsync(),无法再接收到消息。
客户端代码:

try
{
    var cts = new CancellationTokenSource();
    var client = new UdpClient(new IPEndPoint(IPAddress.Any, 10000));
    Task.Run(async () => 
    {
        while (true) 
        {
            await Task.Delay(100, cts.Token).ConfigureAwait(false);
            if (_client != null && _client.Available != 0) 
            {
                if(cts.Token.IsCancellationRequested) break;
                var res = await _client.ReceiveAsync().ConfigureAwait(false);
                if (res.Buffer != null && res.Buffer.Length > 0) 
                {
                    Console.WriteLine(res.Buffer);
                }
            }
        }
    }, cts.Token);
}
catch(Exception e)
{

}

服务端UdpClient关闭后,客户端catch陷入无限等待,且无法捕获到异常,服务端重启后也无法再次接收服务端消息。

解决方案:服务端断开后,客户端会收到远程主机关闭连接的异常,将异常捕获移动到内部,并捕获SocketException异常,当捕获到的异常代码为ConnectionReset时,表示远程主机关闭,不做处理即可,下次服务端重启后可正常连接。

var cts = new CancellationTokenSource();
var client = new UdpClient(new IPEndPoint(IPAddress.Any, 10000));
Task.Run(async () => 
{
    while (true) 
    {
        await Task.Delay(100, cts.Token).ConfigureAwait(false);
        if (_client != null && _client.Available != 0) 
        {
            if(cts.Token.IsCancellationRequested) break;
            try
            {
                var res = await _client.ReceiveAsync().ConfigureAwait(false);
                if (res.Buffer != null && res.Buffer.Length > 0) 
                {
                    Console.WriteLine(res.Buffer);
                }
            } 
            catch (SocketException ex) 
            {
                if(ex.SocketErrorCode == SocketError.ConnectionReset)
                {
                    //远程主机关闭连接
                }
                // 处理接收超时或其他异常
                else Console.WriteLine($"Socket exception: {ex.Message}");
            }
        }
    }
}, cts.Token);

posted @ 2024-10-17 09:47  Zzz1207  阅读(170)  评论(0编辑  收藏  举报