Jump to content

  • Log In with Google      Sign In   
  • Create Account

High latency cause frequent connection loss


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 bliztertoto   Members   -  Reputation: 100

Like
0Likes
Like

Posted 15 April 2012 - 06:26 PM

Hello,

I am working on a multiplayer action platformer right now.

The game uses only tcp. It is an action game so I am sending about 1 to 3 packets each frame.

The game is stable right now but we are encountering an issue. Players with high latency (typically european players), are getting frequent disconnects while playing the game. Players with a low latency can play without any problems.

Do you guys have any ideas about what might be causing this? Is it an issue with tcp itself that requires software handling?

I'm using SFML for the networking, nagle is disabled.

Thanks!

Sponsor:

#2 rip-off   Moderators   -  Reputation: 8749

Like
0Likes
Like

Posted 16 April 2012 - 02:46 AM

The game uses only tcp.

I hope I can assume your code correctly handles the fact that TCP is a stream based protocol, rather than a packet based protocol.

It is an action game...

Action games generally use semi-reliable UDP rather than TCP. This is because in the event of packet loss TCP forces you to wait for the earliest data to arrive before giving you later data - data that might already be delivered! You might have up-to-date game state sitting in a TCP buffer, but it is waiting for data from the previous frame to arrive before you'll get to see it.

... so I am sending about 1 to 3 packets each frame.

How frequent are frames? If you're aiming for 60FPS, then you should probably only be sending data every N frames. Or rather, your networking code should have its own "ticks per second" value - independent of rendering.

Which direction are these packets going?

Players with high latency (typically european players), are getting frequent disconnects while playing the game. Players with a low latency can play without any problems.

What is your definition of high latency? It would be interesting if you could estimate the packet loss these players experience. Perhaps their disconnections co-incide with a bout of packet loss.

Do you have a system to automatically "kick" players which fall too far behind? If so, do you log that this is the reason for disconnection?

#3 bliztertoto   Members   -  Reputation: 100

Like
0Likes
Like

Posted 16 April 2012 - 09:04 AM

Hey, thanks

I was using udp before but the combinaison of tcp and udp seemed to add congestion and more frequent disconnects.

I read somewhere that tcp is not really slower than udp right now in 2012 because of all the hardware acceleration and optimized drivers for it. So I tried it all tcp and I didn't see a difference (except that people seemed to drop less often).

Only tcp allows me to forget about nat punch through and it seemed like a good idea to stick with tcp only.

My code handle tcp as a stream protocol in a non-blocking multithreaded way.

When I mean high latency, I mean about 350 to 500 milliseconds delay.

Client send data to the server then resend it to all other clients.

I am sending important updates every two frames, but there are a lot of one-time events so this might cause congestion. I monitored using perfmon and the game uses about 8ko/s of bandwidth. Is this unusualy high for tcp?

Is there a way to check what the current tcp buffer size is, and what is the maximum? Does a full tcp buffer cause a disconnect?

I don't have any system right now to kick players or disconnect them, so it must be on a lower level.

#4 hplus0603   Moderators   -  Reputation: 5717

Like
0Likes
Like

Posted 16 April 2012 - 10:25 AM

TCP is never SLOWER than UDP. What it is, is an in-order stream protocol. This means that the receiving application will never see data out-of-order, which means waiting for a re-transmit if a packet is lost. UDP will let you see data out-of-order, and delivers whatever packet comes into the computer, to the application, as soon as it's available. The main reason to use UDP is to aviod the stall-waiting-for-retransmit before delivering later data in the case of packet drop.

I am sending about 1 to 3 packets each frame.


"Packets" are something you send on the network -- typically by sending a length counter and then that much data. You should never need to send more than one packet per frame. If "frames" means "graphics frames" or "simulation frames," most games will send one packet per N frames, for a packet rate between 10 and 20 packets per second. Within packets you will have "messages" which is your own way of slicing data about different things to different parts of your application.

Finally, what does "disconnect" mean? Does the socket recv() call return -1? Does the send() call return 0? Something else?

Note that SFML does not document whether it packetizes messages or not -- my guess is it's a zero-value wrapper on sockets, and thus a send() for 20 bytes followed by a send() for 35 bytes may receive in a single recv() for 55 bytes. Or one recv() for 12 bytes and one recv() for 18 bytes and one recv() for 25 bytes. Or some other combination.

enum Bool { True, False, FileNotFound };

#5 bliztertoto   Members   -  Reputation: 100

Like
0Likes
Like

Posted 16 April 2012 - 11:05 AM

This is true, I meant messages instead of packets.

By disconnect, I meant I get sf::Socket::Disconnected from TcpSocket::Receive()

This is from SFML:

Socket::Status TcpSocket::Receive(char* data, std::size_t size, std::size_t& received)
{
    // First clear the variables to fill
    received = 0;
    // Check the destination buffer
    if (!data)
    {
	    Err() << "Cannot receive data from the network (the destination buffer is invalid)" << std::endl;
	    return Error;
    }
    // Receive a chunk of bytes
    int sizeReceived = recv(GetHandle(), data, static_cast<int>(size), 0);
    // Check the number of bytes received
    if (sizeReceived > 0)
    {
	    received = static_cast<std::size_t>(sizeReceived);
	    return Done;
    }
    else if (sizeReceived == 0)
    {
	    return Socket::Disconnected;
    }
    else
    {
	    return priv::SocketImpl::GetErrorStatus();
    }
}


#6 0BZEN   Crossbones+   -  Reputation: 2025

Like
0Likes
Like

Posted 19 April 2012 - 05:39 AM

How much data are you sending? Are you running into your bandwidth limit? Do you get lag spikes?

Use tools like wireshark to analyse your traffic.

Everything is better with Metal.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS