Java TCP Delay

I am developing an Android application that interacts with a TCP TCP server through a WLAN connection. The Android application is a game in which sprites move around the screen. Whenever a sprite moves, AndroidClient sends its coordinates to a Java server, which then sends data to other clients (maximum 4 clients). The server processes each client in a separate thread, data updates are sent approximately every 20 ms. Each packet consists of 1-10 bytes. I am on a network with 70 Mbps (with my wireless network about 15 Mbps).

I have problems with an unstable connection and there is a latency of about 50-500 ms. every 10th-30th package. I set tcpNoDelay to true, which stopped the constant delay of 200 ms, although it still lags significantly. Since I'm completely new to both Android and the web, I don’t know whether this should be expected or not. I am also wondering if UDP is suitable for my program, as I am interested in sending updates faster than every packet that arrives correctly.

I would appreciate any advice on how to avoid / work around this problem with a delay. General tips on how to implement such a client-server architecture will also be welcome.

+4
source share
2 answers

On a wireless LAN, you will sometimes see dropped packets, which leads to retransmission of packets after a delay. If you want to control the delay before retransmission, you will almost certainly have to use UDP.

+2
source

You definitely want to use UDP. For the game, you do not care if the sprite position is incorrect for a short time. Thus, UDP is ideal in this case.

Also, if you have any control over the server code, I would not use separate threads for clients. Topics are useful if you need to make calls in libraries that you don’t have and that can be blocked (for example, because they touch a file or try to make additional network communications). But they are expensive. They consume a lot of resources and, as such, actually make things slower than they can be.

So, for a network game server where latency and performance are absolutely important, I would just use a single thread to process a queue of commands that have state, and then make sure you never perform an operation that blocks. Therefore, each command is processed in order, the state is evaluated and updated (for example, a laser explosion intersects with another object). If a command requires a lock (for example, reading from a file), you need to perform a non-blocking read and set the state of this command accordingly, so that your shell will never block. The key is that the shell can never be blocked. It just starts in a loop, but you will need to call Thread.sleep (x) accordingly so as not to waste CPU.

As for the client side, when the client sends a command (for example, they started the laser or some of them), the client would create a response object and insert it into the card with the sequence identifier as the key. Then it will send a request with a sequence identifier, and when the server responds to this identifier, you simply look at the response object on the map and decode the response to this object. This means that you can perform parallel operations.

0
source

Source: https://habr.com/ru/post/1401662/


All Articles