TCP Network, use Callbacks!

Are you losing TCP data now and then?

Are you struggling with your TCP Sockets loosing data now and then? I was losing data and had my hair removed by my own hands (almost).

I had a simple loop like the following to receive data from the server..

                   byte[] bytes = new byte[sCHAR_BUFFER_SIZE];


                    int bytesRec = senderSock.Receive(bytes);

                    if (bytesRec > 0)
                    {
                        String theMessageToReceive = System.Text.Encoding.Unicode.GetString(bytes, 0, bytesRec);

                        while (senderSock.Available > 0)
                        {
                            bytesRec = senderSock.Receive(bytes);
                            theMessageToReceive += System.Text.Encoding.Unicode.GetString(bytes, 0, bytesRec);
                        }
                        sEventMessage2 = theMessageToReceive;

                        sCallBacker.serverCallbackToClient(theMessageToReceive);
                    }
                    else
                        senderSock.Close();

And I was loosing data because all of a sudden the connection could close and the loop would break cutting my message in half because senderSock.Available would return 0 though I still had data to receive.


I changed it to a callback instead which was much better, like this..

        private static void receiveDataFromServer(Socket senderSock)
        {
            try
            {
                StateObject state = new StateObject();
                state.mWorkSocket = senderSock;

                senderSock.BeginReceive(state.mBuffer, 0, StateObject.cBufferSize, 0,
                    new AsyncCallback(receiveDateFromServerLoopBack), state);
            }
            catch (Exception exc) { sBusy = false; sEventMessage = exc.ToString(); }
        }
        private static void receiveDateFromServerLoopBack(IAsyncResult ar)
        {
            try
            {
                StateObject state = (StateObject)ar.AsyncState;
                Socket client = state.mWorkSocket;

                // Receives data from a bound Socket.  
                int bytesRec = client.EndReceive(ar);

                if (bytesRec > 0)
                {
                    // Converts byte array to string  
                    state.mTheText += System.Text.Encoding.Unicode.GetString(state.mBuffer, 0, bytesRec);

                    // Continues to read the data till data isn't available  
                    if (!state.mTheText.EndsWith("<Server Quit>"))
                    {
                        client.BeginReceive(state.mBuffer, 0, StateObject.cBufferSize, 0,
                        new AsyncCallback(receiveDateFromServerLoopBack), state);
                    }
                    else
                    {
                        state.mWorkSocket.Close();
                        sBusy = false;
                        sCallBacker.serverCallbackToClient(state.mTheText);                        
                    }
                }
                else
                {
                    state.mWorkSocket.Close();
                    sBusy = false;
                }
            }
            catch (Exception ex) { sEventMessage2 = ex.Message.ToString(); }
        }

Aarrrrgh and I've been working my brains out for several days to find what was causing the data bail out. Finally it was working!

Just wanted to share this with others that might be or end up in the same situation.

See you!

Kommentarer