I'm trying TCP communication using VB.NET and using the TcpClient method.

All is working fine but I'm having trouble keeping my message seperate from each other.

For example, my message have an header and footer and can range in size from very small (32 bytes) to quite large (64k). The problem I have is that when messages are being sent quickly they will arrive together. For example, if two 32 byte messages are sent they will arrive as 64 bytes. This is no good as I need to process them seperately.

So my question is:- Is there a way to easily separate my messages using a built in feature of the TcpClient so that the "reading" will give me the correct amount of bytes each time corresponding to the amount of bytes I have sent per message?

I'm not going to say it's impossible, but I will say I see no way to configure this on the TcpClient class, you're asking for something that may require Socket-level configuration, and for a well-designed protocol it's a non-issue.

Networking protocols tend to consider data as a stream rather than individual packets. This works great for things like file transfer or HTTP, where a single logical piece of data is being sent via several packets. The layers of abstraction between you and the bits strip out the TCP headers and all you see is a stream of data; it's a heck of a lot easier than being handed a ton of packets from which you have to unwrap TCP headers and IP headers.

When your protocol involves small packets of information, this may not work so well. The forces contending against you aren't confined to TCP though; your network hardware might be part of the process. I'm not counting exact numbers, but the TCP header's something like 24 bytes, and a real packet's also going to include an IP header and some other headers. To network hardware, that makes sending a packet a pretty expensive proposition. I imagine most network hardware has a buffer for data and only sends data when either the buffer is full or some timeout has elapsed. So when you send 32 bits of data, it might get plopped in the buffer and wait a while. If you send another 32 bits over the same connection before the timeout elapsed, as far as the hardware's concerned you're sending 64 bits of data. I could be making this up, but it seems feasible.

Plus, on the receiving end you're still up the creek. TcpClient doesn't expose data as individual received packets; it exposes them as a stream. Even if you can get your data sent out as two individual packets, multiple packets might arrive before you attempt to read data. All TcpClient can tell you is how much data it has; by the time you ask it's tossed the TCP/IP headers that might separate the packets. I believe the only way you can get individual packets is to use the Socket class, set it up to read raw packets, then interpret the TCP/IP headers for the individual packets. If the data is indeed coming in as two packets, this would let you see two packets, though what you'd really see is a bunch of bytes which you then have to interpret to figure out if there was more than one packet or not. Raw sockets requires Administrator privileges and you'll have to deal with corner cases like when you ask for data before a packet has fully arrived. What I'm trying to make clear is using Socket would be dumb, there's a solution that should make you slap your forehead.

Put a size field in your header that indicates the size of the packet. That way, when you receive 64 bytes, you can check the header to see if you have 1 64 byte packet. If not, you'll know how much to read for the first packet and you can process it. Then, you can check the header of the next packet to get its size, and so on until no data remains. This is how TCP solved the problem, and it's a good way to solve the problem in your own protocols.

The first one was the length field which could be checked to see if there was any outstanding data needing to be received.

The second contintinually checked the buffer for the header and footer of my messages and if it was found then it would remove and process that message only and leave the remainder behind to be added to by the ongoing read process.