Search code examples
c#socketsasynchronoustcpclient

C# client unable to trigger server back to back


I have a Kinect sensor connected to a PC and my application that is requesting frames over a TCP connection that is residing on another PC. My problem is that I am unable to trigger two requests and get frames back to back.

This is the code on the server side which is connected to the sensor:

while(running)
{
    if (networkStreamReceive.DataAvailable)
    {
        byte[] clientRequest = new byte[8];
        networkStreamReceive.Read(clientRequest, 0, clientRequest.Length);              
        string clientData = System.Text.Encoding.ASCII.GetString(clientRequest);
        clientData = clientData.Substring(0, clientData.IndexOf("$"));
        if (clientData == "1")
        {
             // Process sensor data.
             // Takes about 5-15 ms.
        }                           
    }
}

On the client side, it makes a request as follows:

NetworkStream serverStreamSend = clientSocketSend.GetStream();    

//Send the request.
byte[] outStream = System.Text.Encoding.ASCII.GetBytes("1$");
serverStreamSend.Write(outStream, 0, outStream.Length);
Thread.Sleep(800); // Works for 1000ms and above.
serverStreamSend.Write(outStream, 0, outStream.Length);

receivedFrame = receiveFrame();
receivedFrame = receiveFrame();

where receiveFrame reads the data from the stream.

This only works if I add a sleep of at least a second on the client side. If I remove that sleep, I see that the client is able to fire both the requests, but is stuck reading the second receiveFrame.

On the server side, I see the first trigger come in, but the second one does not come through. I am unable to understand why this is so when the time to process the sensor data is only about 10-15ms.


Solution

  • The second one did come through, but your code doesn't notice because you aren't checking the return value of the Read() method to see just how much data was actually available.

    When the client is sending the requests quickly enough, they get combined into a single transmission and both requests are available in a single call to Read(). But your code will check only the first request in that transmission and will throw away the second one.

    Assuming the $ character is a delimiter for your protocol, you should change your server side so that the server continues to read data from the received buffer all the way to the end, treating each $-delimited section as a single request.

    If the $ character isn't a delimiter, then you're going to need to decide what you will use for a delimiter and include that your protocol.