C# TcpClient Networkstream 读取超时 - 从 ReadAsync (Telnet) 识别字符串

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

我正在使用 TcpClient 和 Networkstream 连接到远程 Telnet 服务器,只要从服务器传递预期的答案,一切都会正常 - 但是我想添加一个超时,以捕获异常。

这是我当前的代码,我正在等待“用户名”

byte[] buffer = new byte[4096];

string response = "";
int bytesRead;

var cancellationTokenSource = new CancellationTokenSource();
cancellationTokenSource.CancelAfter(5000); //does not work as timeout

while (!response.Contains("Username"))
{
    try
    {
        bytesRead = await targetClient.GetStream().ReadAsync(buffer, 0, buffer.Length, cancellationTokenSource.Token);
        response += Encoding.ASCII.GetString(buffer, 0, bytesRead);
        Console.WriteLine($"Answer from Telnet-Server: {response}");
    }
    catch
    {
        Console.WriteLine("catch");
        break;
    }
}

如果我对 ReadAsync 函数的理解正确 - 取消令牌不被考虑在内 - 所以这不是添加超时的方式。

是否可以添加超时?也许是第二个工作线程,它在 5 秒后触发,如果响应不包含“用户名”,我就会跳出 while 循环? 或者我应该将 ReadAsync 更改为支持超时的同步方法? 或者我应该将 Telnet 服务器中的所有内容读入队列,并只询问队列是否包含相关关键字,例如“用户名”,这可能吗?

但我认为还有更好的方法,对吧?

谢谢

c# .net timeout tcpclient networkstream
1个回答
0
投票

我真的不知道这个方法是否可行,但它确实有效。如果有什么坑可以评论吗?

static async Task<string> WaitForPromptAsync(NetworkStream stream, string prompt, TimeSpan timeout)
{
    byte[] buffer = new byte[1024];
    StringBuilder response = new StringBuilder();
    DateTime startTime = DateTime.Now;

    while (DateTime.Now - startTime < timeout)
    {
        if (stream.DataAvailable)
        {
            int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

            response.Append(Encoding.ASCII.GetString(buffer, 0, bytesRead));
           
            if (response.ToString().Contains(prompt))
            {
                return response.ToString();
            }
        }

        await Task.Delay(100); // is that OK?
    }

    return response.ToString();
}

例如:

receivedData = await WaitForPromptAsync(stream, "Username", TimeSpan.FromSeconds(2));
if (receivedData.Contains("Username"))
{ //do something
}
else
{ //timeout occured
}
© www.soinside.com 2019 - 2024. All rights reserved.