C# - TcpClient 在 ConnectionAborted 套接字错误后首次读取非常慢

问题描述 投票:0回答:0

我目前正在编写与使用 TCP/IP 的设备交互的代码。 15 秒不活动后,设备将发送 FIN 数据包以断开连接。我正在使用 Polly 进行重试,确保处理 TcpClient 对象,实例化一个新实例,然后在再次重试 IO 操作之前重新连接到 IP/端口。

在这种情况下,我试图从连接的套接字读取响应。重试策略有效,我得到了响应,但我注意到当它确实必须重试时(由于

ConnectionAborted
套接字异常),大约需要 15 秒才能完成将字节读入缓冲区。我没有做过很多网络编程,所以我在这方面比较无知,我不知道为什么要花这么长时间。

// Retry policy and the TcpClient are private member variables in this case
_readRetryPolicy = Policy.Handle<IOException>()
    .RetryAsync(3, onRetryAsync: async (_, _) =>
    {
        Disconnect();
        await ConnectAsync(_ip!, _port).ConfigureAwait(false);
    });

public async Task<byte[]> ReadResponseAsync()
{
    if (_tcpClient is not TcpClient { Connected: true })
    {
        Disconnect();
        await ConnectAsync(_ip!, _port).ConfigureAwait(false);

        // Possible StackOverflowException but I'm just hacking at this problem right now
        return await ReadResponseAsync().ConfigureAwait(false);
    }

    var buffer = new byte[32];
    var responseBytesStream = Enumerable.Empty<byte>();
    int numBytesRead = 0;
    do
    {
        numBytesRead = await _readRetryPolicy.ExecuteAsync(() => _tcpClient.GetStream().ReadAsync(buffer).AsTask()).ConfigureAwait(false);
        responseBytesStream = responseBytesStream.Concat(buffer);
    }
    while (_tcpClient.GetStream().DataAvailable);

    return responseBytesStream.ToArray();
}

public void Disconnect()
{
    if (_tcpClient is TcpClient c) c.Dispose();
    _tcpClient = null;
}
c# network-programming tcpclient
© www.soinside.com 2019 - 2024. All rights reserved.