65.9K
CodeProject is changing. Read more.
Home

Messaging with TCP socket

starIconstarIconemptyStarIconemptyStarIconemptyStarIcon

2.00/5 (6 votes)

Dec 22, 2004

2 min read

viewsIcon

44984

An article on sending messages with TCP and message handling.

Introduction

This is my first article on Code Project and I am glad that I am here. I want to share on of my experiences about TCP messaging. When I was a beginner in socket programming, I had written some socket programs that send messages to notify the user about different events. Some times, messages are lost and it seems no event occurred. Also, some times, I received a message that I didn't send!!! This was my problem, but why?

Background

When two computers are connected by socket, OS uses some internal buffer for storing, sending and receiving data. If second data message is received before using first message, these two messages may be read at once, and if programmer doesn't care about this saturation, second message will be lost and the program actually services just the first message.

Also, maybe one message is bigger than the OS buffer and it splits to two or more IP packets. At this time, program receives messages that was never sent to it, with wrong body! If program isn't well designed, it may crash or work crazy!

My solution

For preventing those problems, we must define some special message format for ourselves and use this format for reading messages. General format of message is:

message header -> message body --> message footer

Message footer isn't used usually, so let's delete footer and use this format:

message header -> message body

One important point is that the header must contain message length, so we can split packets and also reconstruct split messages. One simple header can be like this:

message length (int ) , message type (int)

In this format, we have an 8 byte message header and we can easily split messages. Also, we need a buffer for storing messages. So, when a new packet is received, the program must do the following steeps:

  1. store new packet at message buffer
  2. read 4 first bytes from buffer (let's call it nSize)
  3. if nSize > length(buffer), read nSize (this is one message) and process this message.

    else return

  4. go to 2

And here is the pseudo code for this:

HRESULT hr = NOERROR;
while (m_ReadBuffer.GetBufferLen() > sizeof(int)/*packet_len_size */)
{
  int nSize = 0;
  CopyMemory(&nSize, m_ReadBuffer.GetBuffer(), sizeof(int));
  if (nSize && m_ReadBuffer.GetBufferLen() >= nSize)
  {
    int nTrueSize = nSize+1;
    PBYTE RecPacket = new BYTE[nTrueSize ];
    m_ReadBuffer.Read(RecPacket,nSize);
    // read and remove data form buffer

    TRACE(_T("Read %d byte form rec buffer\n"),nSize);
    RecPacket[nTrueSize-1] = NULL;
    PktHeader * header;
    header=(PktHeader *)RecPacket;
    int OverHeadLen = sizeof(PktHeader );
    hr =DataRec(&RecPacket[OverHeadLen], nSize-OverHeadLen, 
                header); // proccess message here
  }
}

return hr;