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:
- store new packet at message buffer
- read 4 first bytes from buffer (let's call it
nSize
)
- if
nSize
> length(buffer)
, read nSize
(this is one message) and process this message.
else return
- go to 2
And here is the pseudo code for this:
HRESULT hr = NOERROR;
while (m_ReadBuffer.GetBufferLen() > sizeof(int))
{
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);
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);
}
}
return hr;
I had worked as programmer,project manager,web developer for more than 3 years, and have worked on programming personaly for more than 10 years.
I have worked in university as a teacher for 8 years.
my favorite langueges are : VC++,C#,ASP.NET,PHP