Many small packages is fine. In fact, if you are worried about TCP overhead, just insert a
bufferstream that collect up to 1500 chars (or whatever your TCP MTUs is, best to request it dynamically), and deal with the problem in one place. Doing so spares you the overhead of ~40 bytes for every extra package you would otherwise have created.
That said, it's still better to send less data, and building larger objects help there. Ofcourse it's smaller to send
"UID:10|1|2|3 than to send
UID:10;x:1UID:10;y:2UID:10;z:3. In fact, also at this point you should not be reinventing the wheel, use a library like protobuf that can decrease data like that to a 10 byte string or less.
Only thing you should not forget is to insert a
Flush commands on your stream at relevant locations, because as soon as you stop adding data to your stream, it might wait infinite before it send anything. Really problematic when your client is waiting for that data, and your sever wont send anything new until the client send the next command.
Package loss is something you can affect here, marginally. Every byte you send can potentially be corrupted, and TCP will automatically request a retransmission. Smaller packages means a lower chance for every single package to be corrupted, but because they add up on the overhead, you send even more bytes, increasing the odds of a lost package even more. When a package is lost, TCP will buffer all succeeding data until the missing package is resend and received. This result in a large delay (ping). While the total loss in bandwidth because of package loss might be negligible, the higher ping would be undesirable for games.
Bottom line: Send as little data as possible, send large packages, and do not write your own low level methods to do so, but rely on well known libraries and methods like
bufferstream and protobuf to handle the heavy lifting.