The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
SDL_UDP_Send very slow
Meldryt


Joined: 22 Oct 2014
Posts: 36
Location: Munich
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.
Meldryt


Joined: 22 Oct 2014
Posts: 36
Location: Munich
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]
Meldryt


Joined: 22 Oct 2014
Posts: 36
Location: Munich
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_UDP_Send very slow
MrOzBarry


Joined: 26 Jun 2010
Posts: 620
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,
-Alex


On Sun, Feb 22, 2015 at 10:50 AM, Meldryt wrote:
Quote:
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

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL_UDP_Send very slow
john skaller
Guest

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

Quote:

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

http://felix-lang.org



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
SDL_UDP_Send very slow
MrOzBarry


Joined: 26 Jun 2010
Posts: 620
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).


On Sun, Feb 22, 2015 at 5:08 PM, john skaller wrote:
Quote:

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

Quote:

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

http://felix-lang.org



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


SDL_UDP_Send very slow
Jonas Kulla
Guest

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



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.
Meldryt


Joined: 22 Oct 2014
Posts: 36
Location: Munich
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.
SDL_UDP_Send very slow
john skaller
Guest

On 23/02/2015, at 3:01 PM, Alex Barry wrote:

Quote:
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..


Quote:
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.

Quote:

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.

--
john skaller

http://felix-lang.org



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
SDL_UDP_Send very slow
ludi
Guest

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








------------------ Original ------------------
From: "john skaller";;
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:

Quote:

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

http://felix-lang.org



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Meldryt


Joined: 22 Oct 2014
Posts: 36
Location: Munich
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_UDP_Send very slow
MrOzBarry


Joined: 26 Jun 2010
Posts: 620
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:
Quote:
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

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Re: SDL_UDP_Send very slow
Meldryt


Joined: 22 Oct 2014
Posts: 36
Location: Munich
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());
      }
SDL_UDP_Send very slow
Luke Groeninger
Guest

Quote:
On Feb 27, 2015, at 7:14 AM, Meldryt wrote:
max length of 192 and a data length of 96.

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

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

Quote:
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_UDP_Send very slow
MrOzBarry


Joined: 26 Jun 2010
Posts: 620
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:
Quote:



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

max length of 192 and a data length of 96.


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


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



Quote:
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

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL_UDP_Send very slow
Daniel Gibson
Guest

On 02/27/2015 07:24 PM, Alex Barry wrote:
Quote:
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,
Daniel

Quote:
On Fri, Feb 27, 2015 at 1:22 PM, Luke Groeninger
<mailto:> wrote:



Quote:
On Feb 27, 2015, at 7:14 AM, Meldryt
<mailto:> wrote:

max length of 192 and a data length of 96.

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

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

Quote:
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
<mailto:
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org




_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Meldryt


Joined: 22 Oct 2014
Posts: 36
Location: Munich
Quote:
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.
Re: SDL_UDP_Send very slow
Alex


Joined: 19 Sep 2014
Posts: 35
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.
SDL_UDP_Send very slow
john skaller
Guest

On 28/02/2015, at 6:52 AM, Meldryt wrote:

Quote:

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.


--
john skaller

http://felix-lang.org



_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org