Im am currently writing some test code for an online multiplayer snake game. (achtung die kurve - clone). I am using TCP Sockets atm.
new game round: I send a short array from the server to the clients with their initial random x and y positions. > 2 short per player
running game: I send left/right pressed/released byte from clients to server. Every 30ms, the server updates the player positions, and sends the x and y offset of each player to its previous position. in a byte array. > 1 byte per player
I am using socket.setTcpNoDelay(true); so +/- 33 tcp packets are sent each second, holding a byte array of maximum length 6. (max 6 players).
But I read somewhere that the header of a TCP packet is 40bytes? (20 TCP + 20 IP)
(40+6)*33 = 1.5 kb/sec sent to each player makes 9kb/sec upload bandwith on the server? Those 9kb only hold around 1.2kb of data.
How should I reduce this overhead? Will UDP help? Or do a need to change the way I communicate between client and server.
One thing I tried for now is update the world every 25 ms, and sent one packet holding 2 gamestates only every 50 ms. Then the client shows frame 1, waits 25ms, and then shows frame 2. This seems to work ok, but it's still alot of traffic.
I could send the player movements to all the clients, and let them do the game logic, but then they will all be out of sync? :s
One more question: is there a way to measure the networktraffic that is being used by my java application? I know there are programs such as ethereal or netlimiter to analyze network traffic, but I would like to know it from inside inside the java application, to show average down- and upstream on the screen for example.
Most other games stick to UDP for this very reason. TCP is useful when you want a reliable pipe between two nodes (guaranteed delivery in order without application intervention). This comes at a cost, obviously. As well, if the socket gets borked, it can stall and your game won't get anything until it can right itself.
UDP is designed when you want fast packet-oriented traffic that will not care about failing. If the packet gets there, great. If not, no worries. This means the application has to handle failures. One way to do this is to send full frames every so often and update frames between. If a client misses an update frame, their view of the world will be incorrect until the next full frame arrives.
The effect is very noticable if you've ever played first person shooter games over a bad connection (like a modem). Not only does everyone lag behind their real position, but occassionally the whole world freezes, hiccups and the people jump to their correct positions. Over broadband, this is quite rare.
I just Googled myself a handy TCP/IP Guide that covers the UDP Header. Spoiler warning: it's 8 bytes. I assume it also has the IP header of 20 bytes, so you're saving 12 (or more) bytes per packet. I say "or more" because I've read elsewhere of different TCP header formats. I don't know exactly how that would work since it's a standard, but I've never studied it to that detail.