designing protocol for multiplayer game

So I’m doing all of the networking for my game with out the use of any library (learning purposes). Currently the transport layer uses TCP and networking is done with NIO. As I am using TCP it means there is no guarantee that all of the bytes for a message will arrive at the same time e.g.

lets say my packet is AABBBAAB I might receive it as AAB BBAA B.

This means that I need a way to detect where a packet starts and were it ends. For this reason the first part of my message should logically be a length so we can see if we need to wait for more bytes to finish building the packet. The next part of my packet is a msg ID that basically tells the receiver what packet you need to build (e.g a ping packet, login packet e.t.c).

However I’m currently stuck on how to structure the rest of the message. Detecting a packets length and Msg ID is easy as they are always 5 and 3 bytes in size respective. What are the best ways to structure the rest of the packet? I need an easy way to identify the remaining fields in the message (basically the content of the message).

as an example lets say I have a packet

Login packet which has fields of 
username = foo 
password  = bar

I could structure the message like so 00100001foobar so that we know the rest of the message is 10 bytes, the packet belongs to login as the id is 001 but how do we know what fields belong to the username and what fields belong to the password?

I think you have it wrong; TCP ensures the packet is received, UDP doesn’t. Packets are received as whole packets, not streamed in. You shouldn’t have this issue.

you sure about that? TCP is a stream protocol and as such it doesn’t know what a packet is. The bytes streamed in TCP are reliable and ordered but it has no guarantee that the entire packet will come in at once. I.e TCP does not provide you with a a 1:1 relationship to the physical packets sent (because TCP doesn’t know what a packet is).

opiop65 was true, packets are indeed received as whole packets, but regardless of this, an old trick is to simply separate the different fields you send in a packet, f.e.:

001-00001-foo-bar

Even if you get 17 packets of one character, you still know what’s the username/password.