How to deal with different packet sizes?

I’ve been working on an MORPG for a while, and I’ve pretty much completed the entire structure for the networking. The current issue I’m dealing with is packet size. Up until now, when receiving packets, I’ve just been using a byte array for the data at a set amount and trimming all the excess 0-bytes that aren’t used.

Here’s part of the packet receiving code:


byte[] data = new byte[1024];
					
int readInt = input.read(data);   // (input instanceof DataInputStream) == true
if(readInt == -1) throw new EOFException();

However, the issue arises when larger packets come into play. The game does everything but rendering and player input on the server-side, and one such instance of a large packet sent to the client is a packet containing heightmap data for the terrain. Now, the heightmap is only 256x256. The data sent in a packet, however, is much larger. As each value of the heightmap is a Float, there will be 256x256x4 bytes sent to the client, approximately 262kb. I can’t just up the length of the byte array in the packet-receiving-code to 263000 bytes, because allocating that much data for every single packet received would be insanely slow and inefficient. Is there a way to figure out the size of the packet received from a DataInputStream before reading all the data? My best guess would be to have the first three bytes of the packet contain the length of the packet or something. I really have no idea what to do here, I started this project as a learning experience. :slight_smile:

Why don’t you just fill as much data into each 1024 packet that you need and send them over one at a time until all the data is sent?

First packet says hey here comes the terrain data, the rest follows until you tell it you’re done sending terrain data.

This is the correct answer. Don’t send the entire thing in one go. As long as each piece makes sense alone, you can rebuild the array on the user’s side.

The first two bytes of my packets identify the Packet ID. If I understand correctly, with what you are saying I’d end up splitting the Heightmap packet into three different packet IDs: The first packet, indicating incoming heightmap data packets, the actual data packets, and the final packet indicating the end of the stream of heightmap packets, correct? Since I’m using TCP I don’t have to worry about them arriving out of order as well, right?

If you’re using TCP, then you’re primarily working with streams not packets.

How the data you write to a stream is segmented into packets is (almost) completely beyond your control, and more importantly is completely irrelevant.
All you should care about is that the data you write to the OutputStream on one end, will be read back from the InputStream at the other.

It sounds like you’ve misunderstood some of the fundamentals.