I have a TCP client / server application and had it working very well on the local machine. However, the minute I used a client on a different machine, only small messages were delivered ( up to 20-30 bytes). The minute the client needed to read larger data if would lock up. What I believe the issue is is that the client is not receiving all of the data being send in one tcp packet. So in other words I had a single call to tcpClient.Client.Receive(tcpBuffer) and assumed that the tcpBuffer had all the data which it did on the local machines. Now the messages that are being send by the server are all terminated in a byte which is unique in a message (0xFD). I am not sure how to deal with this. So one question is, is the NetworkStream.DataAvailable giving you the data that is available on the client or on the server? Do I have to keep reading and looping until I get the 0xFD value? How would one go about doing this efficiently? So basically I would like to replace the tcpClient.Client.Receive(tcpBuffer) with something like the following:
private static byte[] GetTcpResponse()
{
int arrayLength = tcpClient.Client.Receive(tcpBuffer);
if (tcpBuffer[arrayLength - 1] == 0xFD)
{
return tcpBuffer;
}
else
{
//this is where I am hung up
}
}
So where I am hung up can be seem from the above. Do I just do another Receive? What if there is no data yet? Thanks, Tom
TCP is a stream based protocol, it is not a datagram based protocol. You shouldn't rely on the received datagrams having a given size or your data being on any given datagram boundaries; nor should you expect all your data to be received on one single datagram (or on any given number of datagrams). So when you say:
Do I have to keep reading and looping until I get the 0xFD value?
Yes, that's the point; but add a reasonable timeout and proper exception checking so that your application doesn't hang in case the connection fails and you never get that terminating value.
Your code could then be something like this (apart from timeouts, error checking, etc); I haven't tested it but it should help you getting the idea:
private static byte[] GetTcpResponse()
{
var data = new List<byte>();
var buffer = new byte[512]; //size can be different, just an example
var terminatorReceived = false;
while(!terminatorReceived)
{
var bytesReceived = tcpClient.Client.Receive(buffer);
if(bytesReceived > 0)
{
data.AddRange(buffer.Take(bytesReceived));
terminatorReceived = data.Contains(0xFD);
}
}
return data.ToArray();
}