Sending data through Socket leads to lock-up

Whilst working on my engine I noticed something a little odd.

For data transferring I am using TCP. About 60-times a second the client will send a packet containing it’s positional information to the server, and 60 times a second the server sends out positional packets of all entities in the world to all clients.

I know, 60 times a second is overkill! I will reduce this later on (unless it is what’s causing the problem).

After anywhere from 10 - 20 seconds my client seems to lock up when it tries to send data to the server. Here is the send method:

/**
 * This method writes a packet of data to a socket.
 * @param packet
 */
public void send(Packet packet) {
	if (closed)
		return;
	
	if (!socket.isConnected()) {
		close();
		return;
	}
	
	try{
		byte[] ba = packet.buffer.getOutgoing();
		out.write(ba.length & 0xFF);
		out.write(ba.length >> 8 & 0xFF);
		out.write(ba);
		out.flush();
		bytesSent += ba.length + 2;
	}catch(Exception e) {
		close();
	}
}

What’s odd, is that this ONLY happens when I run both the client and server application on my desktop computer. If I connect to my server computer from the client, this does not happen.

Any ideas? o:

i dunno what are you trying to do, but you need to use threads or a ThreadPool to no lock up your game

and if you dont know why is not working, try to make ping from your pc to your server, or check if your firewall is not blocking the data.

somethimes is not problem of the comunication with CLient - Severt, but, our network configuration

Such high frequency updates are only going to have a chance to work on a LAN and with a max of a dozen or two clients.

There are better ways to do networking for multiplayer games. You could watch this talk to get an idea of the main advantages and disadvantages of the few popular methods: http://gdcvault.com/play/1022195/Physics-for-Game-Programmers-Networking

What @pavul hints at is that socket reads are blocking so if you’re running it in the same thread as your game you’re going to have a bad time.

Other than that, what does this sentence mean?:

It means exactly what it reads.

If my home computer runs both the client and the server this bug happens.
If I run my client on my home computer, and have it connect to the server on my server computer, it does not happen.

Socket reads are not blocking if you check the available size before you read them. Regardless, reading is not the problem here. Writing is what randomly causes the game to stop only if I’m connected via localhost.

I’m quite sure this has nothing to do with Blocking, because all blocking does it stop your thread to wait for more data. The problem here is that data IS sent, 60 times a second, but it gets stuck regardless. Something else is happening here.

I seem to remember hearing that when using TCP if you are tons of small packets that are the same they can be filtered by your router of a firewall. Though since you’re on the same machine with both I don’t see how it would take this into account, unless it’s built into TCP…

Anyway does it fail to write and then close the connection? (your catch block?) or does it stop calling send all together?

Stops calling send all together. If an exception was thrown, this would be much nicer :x

send and receive can both block, independently. It’s essential that there are separate threads for sending and
receiving, and that the producer and consumer of the positions not be dependent.

Well then the problem is probably not in the code you’ve provided us, but in the code around it. I suggest logging every method that calls send and go from there.

Edit: You should consider what ddyer has said. I personally think it’s not a blocking issue because the connection works for 10-20 seconds, if it was going to block it would happen almost immediately, but this depends on your first send and receive times. However, I am making a lot of assumptions.

One example that “could” be the problem with your application and that causes send() to block is when the receive buffer of the receiver is full. This can happen when you do not receive() on the server, for some reason.
If that happens then the client’s/sender’s TCP stack will get notified of a TCP window size of 0 bytes by the server and thus has no other choice than to block send() until the receiver actually receives data from the socket’s receive buffer.
So check if you really always drain all available data from the socket using receive() (or read() on the InputStream) on the server-side.

I will check this now! :slight_smile:

Here’s an interesting print-out:

-- GAMESTATE: 60431
Starting to read data
Finished reading data
Parsing packets
Finished parsing packets
Doing stuff with packets
Done doing stuff with packets O:
Sending data to server...
Finished sending data to server!

-- GAMESTATE: 60432
Starting to read data
Finished reading data
Parsing packets
Finished parsing packets
Doing stuff with packets
Done doing stuff with packets O:
Sending data to server...

-- GAMESTATE: 60433
Starting to read data
Finished reading data
Parsing packets
Finished parsing packets
Doing stuff with packets
Done doing stuff with packets O:
Sending data to server...

On the last two gamestates, it doesn’t print that it finished sending the data. (this is printed at the end of the send function from the OP). I wonder why it does it twice, then on the second one it freezes o:

As you enter the next tick, before you finished sending the data in the current tick, clearly something is up with your business logic and the network issues are merely a side effect – either that, or you are creating a new thread every game tick, which might produce similar results, but would be highly unlikely and a recipe for disaster anyway.

That was actually my mistake. I wasn’t properly printing out the “sending data to server…” part.

Here is the updated print-out

-- GAMESTATE: 8436
Starting to read data
Parsing packets
Finished parsing packets
Doing stuff with packets
Done doing stuff with packets O:
Sending data to server...
Finished sending data to server!
-- GAMESTATE: 8437
Starting to read data
Parsing packets
Finished parsing packets
Doing stuff with packets
Done doing stuff with packets O:
Sending data to server...

I’ve ran it 5-6 times now with the same result. So yah, it’s getting caught on the actual sending.

are you flushing receive?

Debug - suspend Client thread (when think its locked)
and watch place.

I remember - have something same with TCP
but not sure
as i remembered - TCP flush not always send data - hi wait some minimal size to send
i may be wrong

-- GAMESTATE: 60431
Starting to read data
Finished reading data
Parsing packets
Finished parsing packets
Doing stuff with packets
Done doing stuff with packets O:
Sending data to server...
Finished sending data to server!

And make something more trivial for test’s - 2 java files (server and client)
*its really hard find error on server when game logic is stopped for some reason)

out.write(ba.length & 0xFF);

Lol - i send same len - first 2-4 bytes XD
And wander why no such thing from “Box” in Java api

I spent the day re-writing everything that has to do with networking.

Everything works now, but I’m not sure why. :-\

At least it’s a lot more efficient.