Accompanying files
Included in the \Buffer\ directory (folder) that came with this is an example code for creating a buffer to help you better understand this code. Included in that project is the DataBuffer code, as explained in section 3.vi.
Packet buffer
Packet buffers take packets and hold on to them, combining packets together until they are ready to be sent. The advantage of this is to avoid as much loss from packet headers and ACKs (in TCP and reliable UDP) as possible. The cost, though, is players receive data that slightly dated. Imagine playing your favorite online game - now imagine playing with a 1000 millisecond ping. Everything will be jumping around, and it'd be impossible to hit anything unless they can hardly move in a second. Those who never experienced such high pings have a hard time imaging how bad it really is, but anyone who has delt with it, especially in a FPS, has probably broke a keyboard or two in frustration.
The Nagle Algorithm
The first kind of buffering we will look at is called Nagle Algorithm, or Nagling for short. This was first created by John Nagle while working at Ford Aerospace. The system was designed to automatically buffer data if the buffer is smaller then the maximum packet size. Data remains in the buffer until the last ACK is received. This is great for systems such as chatting networks, but horrible for online games. Take the following example:
Server builds a packet Server sends packet to client Server builds another packet, packet is buffered Client sends ACK to the server Server sends the next packet
This hardly looks bad at first glance, but you have to take into consideration the natural network latency. It is not uncommon for there to be a 100ms delay between each send, especially on a heavily-accessed server. You can end up with a 300ms, or more, latency on every packet, combined with the natural latency. In bad scenarios, your data can be 500-1000ms old before it ever reaches the client. Nagling is definitely out, unless you want to make a turn-based game. It's a great system, but not for games.
Custom packet buffers
Custom packet buffers are a lot more complex then just using the socket's "send" function every time you want to send data, but for any serious game, it is very important to have because you are either going to have very high latency (if using Nagling) or very high bandwidth usage (if no buffering) and inefficient packets (which could also lead to high latency if trying to send too many packets at once).
The kind of buffer you create depends on what type of packet system you use (as explained in the next system). Optimally, you will want to use binary packets no doubt, which you will store in a byte array. Instead of sending the packet directly to the user, you hold it in an array in memory for them. The CopyMemory API is priceless for this. I do not know about other languages, but the idea is probably the same. You specify where you are copying the memory from, and where you are copying it to, along with how many bytes you are copying over.
Dim b(1 to 10) As Byte Dim c(1 to 5) As Byte 'Destination, source, size CopyMemory b(4), c(1), 5
That chunk of code copies 5 bytes from array c, starting at index 1 (in this case, this is the whole array), to array b, starting at index 4. This will probably change slightly depending on the language you are using. Because I can not cover how to do this in every language, for now on, I will assume you know how to, in the language of your choice, copy a specified amount of memory from one array to another.
Now, instead of your data going into the socket to be sent, it goes into an array located in memory. When you are ready to send your data, you send the whole buffer at once. You will want to make sure that before you copy the data over that it will not push the buffer past the maximum size you want per send. The size a packet can be before it is broken up is called the MTU (Maximum Transmission Unit). For dialup, this is 576, PPPoE broadband, 1492, and finally, Ethernet/DSL/Cable is 1500. I personally like to play it safe and use about 525 bytes as the maximum packet size. First off, it is rare that a packet would ever contain that much information in a game packet except for when you first log in. Secondly, theres plenty of overhead from various things that you have to take into account. So, often, this is not a problem.
How you check for the maximum buffer size being reached depends on the language you use, and personal preference, so I can not be of much help outside of explaining how it works. It is important that you check if the buffer will become too large before sending it, though, instead of after sending it. If the current buffer size + added data size > maximum buffer size, send your buffer then add the packet to the buffer after it is cleared.