C Socket sticky package handling shows examples

  • 2020-05-27 06:57:39
  • OfStack

When socket receives data, it will receive data at point 1 according to the size of buffer, such as:

The other party sent a data volume of 1M, but the local buffer is only 1024 bytes, which means that socket needs to repeat many times to actually receive the whole logical 1 message.
The other party sent 5 2-character messages, the local buffer (size 1024 bytes) will put all 5 messages under the envelope...
So how do you deal with that? I'll start demo with the simplest text message

According to the situation described above, the most important key lies in the treatment of the following three factors

The tag at the end of the message
The end tag is judged when the message is received
What happens when there is no ending tag in buffer this time
I posted the core algorithm:


StringBuilder sb = new StringBuilder();             // This is used to save: received, but not finished messages 
        public void ReceiveMessage(object state)            // This function will be run in a thread 
        {
            Socket socket = (Socket)state;
            while(true)
            {
                byte[] buffer = new byte[receiveBufferSize];  //buffer The magnitude is here 1024
                int receivedSize=socket.Receive(buffer);
                string rawMsg=System.Text.Encoding.Default.GetString(buffer, 0, receivedSize);
                int rnFixLength = terminateString.Length;   // This refers to the length of the end of the message \r\n
                for(int i=0;i<rawMsg.Length;)               // Traversing the received whole buffer The text 
                {
                    if (i <= rawMsg.Length - rnFixLength)
                    {
                        if (rawMsg.Substring(i, rnFixLength) != terminateString)// Non-message terminator, in sb
                        {
                            sb.Append(rawMsg[i]);
                            i++;
                        }
                        else
                        {
                            this.OnNewMessageReceived(sb.ToString());// The message terminator is found, triggering the message receiving completion event 
                            sb.Clear();
                            i += rnFixLength;
                        }   
                    }
                    else
                    {
                        sb.Append(rawMsg[i]);
                        i++;
                    }
                }
            }
        }

How to use this component:


A2DTcpClient client = new A2DTcpClient("127.0.0.1", 5000);
            client.NewMessageReceived += new MessageReceived(client_NewMessageReceived);
            client.Connect();
            client.Send("HELLO");
            client.Close();
 
        static void client_NewMessageReceived(string msg)
        {
            Console.WriteLine(msg);
        }


Related articles: