SDL_UDP_Send very slow

I measure the time before and after calling SDLNet_UDP_Send().
Sometimes its 10 or 20 milliseconds. Thats definitely too slow for my network game.

My packetsize is 192 and i have one ipaddress bounded to the channel.
I tried also SDLNet_CheckSockets and SDLNet_SocketReady, but it didnt help.
I use SDL2 and VS 2010 on Windows 7.

int oldtime=SDL_GetTicks();

  	SDLNet_UDP_Send(m_udpsocket,m_channel,m_packetinput);		
  	if(int(SDL_GetTicks()-oldtime)>3)
  	{
  		SDL_Log("Send NetInput Duration: %i Frame: %i",int(SDL_GetTicks()-oldtime),m_gameinfo->m_currframe);
  	}

[/code]

i read that the winsock functions such as recvfrom() and sendto() could be a problem. When i look into the SDLNet_UDP_Send code, there is nothing that could cause such a huge delay than the sendto() function.

I think you’re going to get much response from the SDL community until you
provide a small code example of what you’re doing. Also, some operating
systems smallest grandularity for milliseconds is 10ms, so your ops may be
taking less.

Also, 10ms is extremely reasonable for a game, and your slow down is
probably waiting for a response over UDP.

From here, I’d really recommend trying to understand the type of
prioritization you want your game to use to get the performance you think
you should be getting.

Think of it this way:
What type of data needs to:

  • be sent and forgotten the fastest
  • have a round trip the fastest
  • be received the fastest
  • be sent and forgotten at any speed
  • be sent on a tround trip at any speed
  • be received at any speed

For games, this will be your main types of sent data. The general paradigm
here is called channels, and you can think of them like road lanes. While
driving, you can appreciate the fast and slow lane, but you won’t
appreciate trying to be fast in the slow lane, or slow in the fast lane.

SDL provides very low level network access where writing a network engine
around it to prioritize packets may not be efficient (it can be done, but
it’s really a separate project altogether). There are libraries that
handle this, or some work arounds. For libraries, enet may be an excellent
choice to light weight, fast and prioritized messages.

If you want to go the SDL route, there is the easy way or the hard way.
The easy way is to just use a secondary socket connection over TCP. TCP is
very slow in comparison to UDP, but can provide you with a stable for data
that you don’t care about the speed (like text chat in game,
initialization/deinitialization, etc.), and leaving UDP for things you want
to be done faster (like updating a player position, physics information,
etc.). This is like a poor man’s two channel system, but it works, and can
guarantee if a client is connected (where UDP may not be able to give this
to you).
Going the hard way means implementing what some would call and networking
kernel, which may or may not run in a separate thread, and when you push
data through it to the server, you would want to mark the channel you want
it to go through, or some sort of priority marker.

To be honest, the hard SDL way is really not necessary when there are other
libraries that do the same job that have been tried and tested, which gives
you one less thing to deal with.

I’m hoping that helps you out a bit,
-AlexOn Sun, Feb 22, 2015 at 10:50 AM, Meldryt wrote:

i read that the winsock functions such as recvfrom() and sendto() could
be a problem. When i look into the SDLNet_UDP_Send code, there is nothing
that could cause such a huge delay than the sendto() function.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL provides very low level network access where writing a network engine around it to prioritize packets may not be efficient (it can be done, but it’s really a separate project altogether). There are libraries that handle this, or some work arounds. For libraries, enet may be an excellent choice to light weight, fast and prioritized messages.

Or perhaps consider 0MQ.

TCP and UDP are generally both entirely incapable of ANY application level
communication: neither protocol can handle the concept of messages.On 23/02/2015, at 4:05 AM, Alex Barry wrote:


john skaller
@john_skaller
http://felix-lang.org

Well, zeromq is great (I’ve used it a pile of times myself), but I can’t
attest to it’s use in games, but it is a reasonable option. I don’t,
however, believe 0mq supports UDP, which is what Meldryt is using at least
now. If he’s struggling with 10ms delays (again, it’s probably slightly
less, but not measurable on his/her system), TCP may not be the route to
take.

Also, I’m not sure what you mean by TCP and UDP being incapable, since
those are the two main basic lowest level sockets available to any system (TCP
is even used in 0mq http://api.zeromq.org/4-0:zmq-bind).On Sun, Feb 22, 2015 at 5:08 PM, john skaller <skaller at users.sourceforge.net wrote:

On 23/02/2015, at 4:05 AM, Alex Barry wrote:

SDL provides very low level network access where writing a network
engine around it to prioritize packets may not be efficient (it can be
done, but it’s really a separate project altogether). There are libraries
that handle this, or some work arounds. For libraries, enet may be an
excellent choice to light weight, fast and prioritized messages.

Or perhaps consider 0MQ.

TCP and UDP are generally both entirely incapable of ANY application level
communication: neither protocol can handle the concept of messages.


john skaller
skaller at users.sourceforge.net
http://felix-lang.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

2015-02-21 19:25 GMT+01:00 Meldryt :

Quote:

int oldtime=SDL_GetTicks();

SDLNet_UDP_Send(m_udpsocket,m_channel,m_packetinput);
if(int(SDL_GetTicks()-oldtime)>3)
{
SDL_Log(“Send NetInput Duration: %i Frame:
%i”,int(SDL_GetTicks()-oldtime),m_gameinfo->m_currframe);
}

[/code]

You might want to try using SDL_GetPerformanceCounter() to get more
accurate results,
although it shouldn’t differ greatly from what SDL_GetTicks() is telling
you.

What i trying to do is called Sync Sim.
All players of the network synchronize the game over the frame.
That means they have 32 ms (for a 30 fps games) to do there work (receiving, sending packets, simulation).

After lot of testing yesterday i can say that the linux and mac version run much better than the windows version.
On windows i have that peaks in SDLNet_UDP_Recv and SDLNet_UDP_Send.

Well, zeromq is great (I’ve used it a pile of times myself), but I can’t attest to it’s use in games, but it is a reasonable option. I don’t, however, believe 0mq supports UDP, which is what Meldryt is using at least now.

Oh, I thought it does … could be wrong though. It supports operations
on a lot of different transports. Some of the operations are available on
UDP and others not. But I could be wrong…

If he’s struggling with 10ms delays (again, it’s probably slightly less, but not measurable on his/her system), TCP may not be the route to take.

Sure, however it could depend on what operations are being used.

My system (I don’t use SDL networking) uses a separate p-thread which
uses the OS specific notification system (kqueue, epoll, etc etc) and
asynchronous sockets, so there’s no delay to the application at all
unless it becomes starved.

Also, I’m not sure what you mean by TCP and UDP being incapable, since those are the two main basic lowest level sockets available to any system (TCP is even used in 0mq).

What I mean is that stream protocols are of no use to most applications.
Applications, generally, require sending messages, not byte streams.

So generally one has to provide a higher level messaging protocol
on top of a stream protocol for it to be useful to an application.

Although it may seem this is easy … the reality is that this is a “bleeding
edge” research topic.On 23/02/2015, at 3:01 PM, Alex Barry wrote:


john skaller
@john_skaller
http://felix-lang.org

Hi,all
I have a blog about messaging using tcp in chinese:
http://blog.csdn.net/deyangliu/article/details/42927997?

------------------ Original ------------------From: “john skaller”;skaller@users.sourceforge.net;
Date: Mon, Feb 23, 2015 06:08 AM
To: “SDL Development List”;

Subject: Re: [SDL] SDL_UDP_Send very slow

On 23/02/2015, at 4:05 AM, Alex Barry wrote:

SDL provides very low level network access where writing a network engine around it to prioritize packets may not be efficient (it can be done, but it’s really a separate project altogether). There are libraries that handle this, or some work arounds. For libraries, enet may be an excellent choice to light weight, fast and prioritized messages.

Or perhaps consider 0MQ.

TCP and UDP are generally both entirely incapable of ANY application level
communication: neither protocol can handle the concept of messages.


john skaller
skaller at users.sourceforge.net
http://felix-lang.org


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I will give SDL_net another try.

As i said before im sending and receiving udp packets with a max length of 192 and a data length of 96.

More precisely i do about 130 send calls per second and about 750 recv calls per second.
So im running my game with two connected players over wlan, sending and receiving udp packets.

Most of the time when i have troubles with not receiving packets i miss them in a row.
And than after several frames i receive all of these old packets with one recv call.
I had always thought that i lost those packets, but i simply receive it too late.

Is it possible that my network,socket… is somehow overloaded at this time?
Do i have to use several sockets for every player and rotate between them or recude number of send/recv to avoid this?

Are you waiting to receive a certain length, or a certain order? UDP is
quite unreliable in terms of order and reliability (packets can be lost).

I think we may have to see some of your network code to better understand
what’s happening.On Fri, Feb 27, 2015 at 9:14 AM, Meldryt wrote:

I will give SDL_net another try.

As i said before im sending and receiving udp packets with a max length of
192 and a data length of 96.

More precisely i do about 130 send calls per second and about 750 recv
calls per second.
So im running my game with two connected players over wlan, sending and
receiving udp packets.

Most of the time when i have troubles with not receiving packets i miss
them in a row.
And than after several frames i receive all of these old packets with one
recv call.
I had always thought that i lost those packets, but i simply receive it
too late.

Is it possible that my network,socket… is somehow overloaded at this
time?
Do i have to use several sockets for every player and rotate between them
or recude number of send/recv to avoid this?


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

MrOzBarry wrote:

Are you waiting to receive a certain length, or a certain order??? UDP is quite unreliable in terms of order and reliability (packets can be lost).

I think we may have to see some of your network code to better understand what’s happening.

im not waiting for a certain order or anything else.

that is how i create my socket and udp packet

Code:
//init UDP socket and address
if (!(m_udpsocket = SDLNet_UDP_Open(1234)))
{
fprintf(stderr, “SDLNet_UDP_Open: %s\n”, SDLNet_GetError());
exit(EXIT_FAILURE);
}
if (SDLNet_ResolveHost(&m_udpaddress,“255.255.255.255”,1234) == -1)
{
fprintf(stderr, “SDLNet_ResolveHost: %s\n”, SDLNet_GetError());
exit(EXIT_FAILURE);
}
if (!(m_packetinfo = SDLNet_AllocPacket(PACKETSIZE)))
{
fprintf(stderr, “SDLNet_AllocPacket: %s\n”, SDLNet_GetError());
exit(EXIT_FAILURE);
}
if (!(m_packetinput = SDLNet_AllocPacket(PACKETSIZE)))
{
fprintf(stderr, “SDLNet_AllocPacket: %s\n”, SDLNet_GetError());
exit(EXIT_FAILURE);
}

that basically is the receive function in which i update the inputdata from the other players.
NETPACKETS is 16, and PACKETSIZE is 192

Code:
UDPpacket **packet = SDLNet_AllocPacketV(NETPACKETS,PACKETSIZE);

bool bSameGame=false;
bool bComplete=false;
int num=0,count=0;
NetInfo* temp,*info;
NetExtraInput* extrainput;
NetExtraInfo* extrainfo;
NetRequest* request;	
NetReady* ready;
NetStart* start;
UDPpacket* selection[NETPACKETS];

num=SDLNet_UDP_RecvV(m_udpsocket,packet);
if(num<1)
{
	SDLNet_FreePacketV(packet);
    return bComplete;
}
else if(num==-1)
{
	SDL_Log("SDLNet_UDP_RecvV: %s\n", SDLNet_GetError());
}

if(m_gameinfo->getRoundState()== ROUND_RUNNING)
{	
    for(int i=0; i<min(num,NETPACKETS); ++i)
    {
        extrainput=((NetExtraInput*)packet[i]->data);
        if((strncmp(extrainput->typeID,"SHOOTERAI_NETINPUT",MAXTYPEID)==0&&extrainput->frame==m_gameinfo->m_currframe-1)
			||strncmp(extrainput->typeID,"SHOOTERAI_NETEXTRAINPUT",MAXTYPEID)==0)
        {           
            selection[count]=packet[i];
			++count;
        }
    }	
	if(count>0)
	{
		bComplete=ReceiveInputPacket(&selection[0],count);
	}       
    SDLNet_FreePacketV(packet);
	}
    return bComplete;
}

thats the send function

Code:
memcpy(m_packetinput->data,m_gameinfo->newreadypacket[m_gameinfo->m_ownID], sizeof(NetInput));
m_packetinput->len = sizeof(NetInput);
m_packetinput->address=m_udpaddress;

if(!SDLNet_UDP_Send(m_udpsocket,m_channel,m_packetinput))
{
SDL_Log(“SDLNet_UDP_Send: %s\n”, SDLNet_GetError());
}

max length of 192 and a data length of 96.

130 send calls per second and about 750 recv calls per second.

when i have troubles with not receiving packets i miss them in a row.

after several frames i receive all of these old packets with one recv call.

I?m not a networking guru, but this sounds suspiciously like you?re overflowing a packet queue at some point in the network stack. It would also explain some of the performance issues involved.

I would highly recommend finding a way to reduce the number of packets transmitted and increase the amount of data being sent per packet. This should, in general, yield better performance over a network anyways - they don?t do well with lots of tiny packets because they are high latency, high bandwidth connections. Wireless lans are particularly bad about this because typically only one client can be transmitting at once - and at the worst case, the base station needs to retransmit the data for the client, further reducing the amount of data a client can transmit each second.

I would also suggest not using an architecture that requires all clients to perform a full state synchronization per frame. There are a ton of techniques involving client prediction and interpolation that can dramatically reduce the frequency in which clients have to synchronize, and help deal with poorly performing networks. A common design pattern for single threaded engines is simple to 1) read incoming data at the start of the frame, 2) process state changes from the server, 3) process state changes from the local client, 4) transmit these state changes to the server without waiting for an acknowledgement, and 5) do graphics/audio rendering until the end of the frame. By allowing the clients to be slightly out of sync on a per-frame basis it allows for significantly higher networking performance (and eliminates the need to repeatedly spam send/receive within a single frame).

-Luke> On Feb 27, 2015, at 7:14 AM, Meldryt wrote:

Packet compression is always a good idea, even if it’s smaller bits of data.On Fri, Feb 27, 2015 at 1:22 PM, Luke Groeninger wrote:

On Feb 27, 2015, at 7:14 AM, Meldryt wrote:

max length of 192 and a data length of 96.

130 send calls per second and about 750 recv calls per second.

when i have troubles with not receiving packets i miss them in a row.

after several frames i receive all of these old packets with one recv call.

I?m not a networking guru, but this sounds suspiciously like you?re
overflowing a packet queue at some point in the network stack. It would
also explain some of the performance issues involved.

I would highly recommend finding a way to reduce the number of packets
transmitted and increase the amount of data being sent per packet. This
should, in general, yield better performance over a network anyways - they
don?t do well with lots of tiny packets because they are high latency, high
bandwidth connections. Wireless lans are particularly bad about this
because typically only one client can be transmitting at once - and at the
worst case, the base station needs to retransmit the data for the client,
further reducing the amount of data a client can transmit each second.

I would also suggest not using an architecture that requires all clients
to perform a full state synchronization per frame. There are a ton of
techniques involving client prediction and interpolation that can
dramatically reduce the frequency in which clients have to synchronize, and
help deal with poorly performing networks. A common design pattern for
single threaded engines is simple to 1) read incoming data at the start of
the frame, 2) process state changes from the server, 3) process state
changes from the local client, 4) transmit these state changes to the
server without waiting for an acknowledgement, and 5) do graphics/audio
rendering until the end of the frame. By allowing the clients to be
slightly out of sync on a per-frame basis it allows for significantly
higher networking performance (and eliminates the need to repeatedly spam
send/receive within a single frame).

-Luke


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Packet compression is always a good idea, even if it’s smaller bits of data.

Not necessarily.
A (IPv4) UDP packet always has 12bytes/96bits.
He wrote “max length of 192 and a data length of 96.” so I assume that
he’s talking about bits (192bit packet length - 96bit data = 96bit header).
So he already has 100% overhead from headers per paket… making the data
even smaller by compression (if that’s even possible for 12byte data)
doesn’t make much sense.
For comparison: It should be safe to use UDP packets with about 1400
bytes of data nowadays (Ethernet: about 1500bytes incl IP+UDP headers,
Internet over PPPoE: about 1492bytes incl. IP+UDP headers, see
http://en.wikipedia.org/wiki/Maximum_transmission_unit ) - with
1400bytes of data you’d have less than 1% overhead from the headers.

So, as Luke wrote: Try to put more data into the same packet - and in
that case compression could actually make sense - so you’d have less
packets per frame.

Maybe just try sending 10 or so packets with dummy data around each
second instead of 130 just to check if that makes any difference with
your latency.
If latency is still high there is a problem in your network, windows’
network stack, SDL_net or your code.
After that you could try some network benchmarking tool (maybe iperf?)
and check if that reports high latency. If it doesn’t, the problem might
be in SDL_net or your code.

(Btw, 130packets/second is just over 2packets per frame @60fps, doesn’t
sound that horrible.)

Cheers,
DanielOn 02/27/2015 07:24 PM, Alex Barry wrote:

On Fri, Feb 27, 2015 at 1:22 PM, Luke Groeninger <luke at dghost.net <mailto:luke at dghost.net>> wrote:

On Feb 27, 2015, at 7:14 AM, Meldryt <herrdersuppen at gmail.com <mailto:herrdersuppen at gmail.com>> wrote:

max length of 192 and a data length of 96.
130 send calls per second and about 750 recv calls per second.
when i have troubles with not receiving packets i miss them in a row.
after several frames i receive all of these old packets with one
recv call.
I?m not a networking guru, but this sounds suspiciously like you?re
overflowing a packet queue at some point in the network stack. It
would also explain some of the performance issues involved.

I would highly recommend finding a way to reduce the number of
packets transmitted and increase the amount of data being sent per
packet. This should, in general, yield better performance over a
network anyways - they don?t do well with lots of tiny packets
because they are high latency, high bandwidth connections. Wireless
lans are particularly bad about this because typically only one
client can be transmitting at once - and at the worst case, the base
station needs to retransmit the data for the client, further
reducing the amount of data a client can transmit each second.

I would also suggest not using an architecture that requires all
clients to perform a full state synchronization per frame. There are
a ton of techniques involving client prediction and interpolation
that can dramatically reduce the frequency in which clients have to
synchronize, and help deal with poorly performing networks. A common
design pattern for single threaded engines is simple to 1) read
incoming data at the start of the frame, 2) process state changes
from the server, 3) process state changes from the local client, 4)
transmit these state changes to the server without waiting for an
acknowledgement, and 5) do graphics/audio rendering until the end of
the frame. By allowing the clients to be slightly out of sync on a
per-frame basis it allows for significantly higher networking
performance (and eliminates the need to repeatedly spam send/receive
within a single frame).

-Luke

_______________________________________________
SDL mailing list
SDL at lists.libsdl.org <mailto:SDL at lists.libsdl.org>
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Not necessarily.
A (IPv4) UDP packet always has 12bytes/96bits.
He wrote “max length of 192 and a data length of 96.” so I assume that
he’s talking about bits (192bit packet length - 96bit data = 96bit header).

192 and 96 are bytes.

The problem is that i have to send at least 1 better 2 packets per frame (60 packets per sec for a 30 fps game), to keep the game synchronized over the network.
I dont know if it makes sense to put the same data multiple times in one packet, if this packet can get lost.

Luke Groeninger wrote:

I?m not a networking guru, but this sounds suspiciously like you?re overflowing a packet queue at some point in the network stack. It would also explain some of the performance issues involved.

I would highly recommend finding a way to reduce the number of packets transmitted and increase the amount of data being sent per packet. This should, in general, yield better performance over a network anyways - they don?t do well with lots of tiny packets because they are high latency, high bandwidth connections. Wireless lans are particularly bad about this because typically only one client can be transmitting at once - and at the worst case, the base station needs to retransmit the data for the client, further reducing the amount of data a client can transmit each second.

I would also suggest not using an architecture that requires all clients to perform a full state synchronization per frame. There are a ton of techniques involving client prediction and interpolation that can dramatically reduce the frequency in which clients have to synchronize, and help deal with poorly performing networks. A common design pattern for single threaded engines is simple to 1) read incoming data at the start of the frame, 2) process state changes from the server, 3) process state changes from the local client, 4) transmit these state changes to the server without waiting for an acknowledgement, and 5) do graphics/audio rendering until the end of the frame. By allowing the clients to be slightly out of sync on a per-frame basis it allows for significantly higher networking performance (and eliminates the need to repeatedly spam send/receive within a single frame).

-Luke

Luke Groeninger is right. Listen to him. For example in my game (I working on now), I need to resync only about 5-6 times per second (according to characters speed). It is much more rare syncing than each frame. In most cases syncing every frame is not needed.

The problem is that i have to send at least 1 better 2 packets per frame (60 packets per sec for a 30 fps game), to keep the game synchronized over the network.
I dont know if it makes sense to put the same data multiple times in one packet, if this packet can get lost.

If your design requires synchronisation you must use TCP/IP and be prepared
to lose visual frames to keep the engine synchronised (at least at a high
frame rate).

So if you use UDP, it is like the real world and you must design
your program that way too. One way is:

Client/Graphics <- TCP -> Local Server <-- UDP -> Master Server

The local server will just have to make guesses as to the state at
each point in time, corrected by unreliable data from the master
server. Laggy corrections will cause unexpected physical effects…

… welcome to real human brain function!

You try killing Diablo in the Chaos Sanctuary at 1 FPS.On 28/02/2015, at 6:52 AM, Meldryt wrote:


john skaller
@john_skaller
http://felix-lang.org