C# TcpClient, getting back the entire response from a telnet device
- by Dan Bailiff
I'm writing a configuration tool for a device that can communicate via telnet. The tool sends a command via TcpClient.GetStream().Write(...), and then checks for the device response via TcpClient.GetStream().ReadByte(). This works fine in unit tests or when I'm stepping through code slowly. If I run the config tool such that it performs multiple commands consecutively, then the behavior of the read is inconsistent. By inconsistent I mean sometimes the data is missing, incomplete or partially garbled. So even though the device performed the operation and responded, my code to check for the response was unreliable. I "fixed" this problem by adding a Thread.Sleep to make sure the read method waits long enough for the device to complete its job and send back the whole response (in this case 1.5 seconds was a safe amount). I feel like this is wrong, blocking everything for a fixed time, and I wonder if there is a better way to get the read method to wait only long enough to get the whole response from the device.
private string Read()
{
if (!tcpClient.Connected)
throw (new Exception("Read() failed: Telnet connection not available."));
StringBuilder sb = new StringBuilder();
do
{
ParseTelnet(ref sb);
System.Threading.Thread.Sleep(1500);
} while (tcpClient.Available > 0);
return sb.ToString();
}
private void ParseTelnet(ref StringBuilder sb)
{
while (tcpClient.Available > 0)
{
int input = tcpClient.GetStream().ReadByte();
switch (input)
{
// parse the input
// ... do other things in special cases
default:
sb.Append((char)input);
break;
}
}
}