Reputation: 675
I am connecting to a remote Telnet Server using TcpClient and Networkstream, as long as the expected answer is delivered from the server everything works fine - however I would like to add a timeout, to catch an exception.
That's my current code, where I am waiting for "Username"
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;
}
}
If I understand the ReadAsync function right - the cancellationToken is not taken into Account - so that's not how a timeout could be added.
Is there any possibility to add a timeout? Maybe some second Workerthread, which fires after 5 Seconds, and if the response does not contain "Username" I break out of the while loop? Or should I change the ReadAsync do a Synchronous Method, which supports a timeout? Or should I read everything from the Telnet Server into a Queue, and only ask if the Queue contains a relevant keyword, like "Username", would that be possible?
But I think there are much better approaches, right?
Thanks
Upvotes: 1
Views: 40
Reputation: 675
I don't really know if this approach is OK, but it's working. Any comments if there are any pitfalls?
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();
}
vor example:
receivedData = await WaitForPromptAsync(stream, "Username", TimeSpan.FromSeconds(2));
if (receivedData.Contains("Username"))
{ //do something
}
else
{ //timeout occured
}
Upvotes: 0