Advertisement

UDP Confusion c++ sockets

Started by July 26, 2018 02:13 PM
33 comments, last by hplus0603 6 years, 3 months ago

So after checking that tcpip protocol doesn't fit my needs (to much delay)

I started to think about udp, however i read that packets can be received not in order or they can be fragmented or dont arrive at all, im using something called text based communication (so actually im sending set of chars through net)

So how would i do that to ensure that when i send hello_set_id(10); the client receives full text, i was thinking of adding a number after each char to ensure that text wont be fragmented like h0e1l2l3o4_5 etc. But then i read that if this packet is fragmented i wouldnt receive a good number and whole string i want to send will be discarded thus i cannot allow that - i may be wrong and packets could be send normally like in tcpip but not in correct order and that would be not that much problem since when im sure that packet that consist max 256 is always sent without some fragmentation.

So what im actually asking?

I dunno :0

maybe how would i handle udp streaming? Do i need only to care about packets that do not come in order or something else?

And why when i send a short text via tcpip i sometimes need to wait a second or more to receive it (while connected to LAN), and what is better for file streaming tcpip or udp?

Intresting topic, i also need to get started with UDP.

 

I dont know any UPD,

i thought u have to send all player coordinates all the time, and discard older packages.

For text i dont know how they would fix.

 

Subscribed

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

Advertisement

UDP is best suited for data that does not need guaranteed delivery.  For example, in a real-time network game where user positions are being broadcast, dropping a packet is no big deal because another packet is coming shortly with updated information.  And, as @the incredible smoker wrote, the sender indexing the packet (for example, with the current time down to ms) will allow the recipient to determine if the packet should be used or discarded because it is older than the last packet received.

In your example, regardless of potential fragmentation, if the recipient of the packet needs to receive the "hello" in order for your system to be effective, then UDP would not be a good choice and TCP would be the right choice.

UDP, by design, is a "best effort" protocol. That means it will do it's best to reach the destination, but it's not guaranteed. These are fast because they get sent and they're done, "see ya later! hope you make it!". TCP on the other hand is guaranteed since it has acknowledgements that get sent, but it also comes at a cost of speed. This one would be like the mom, "hey, call me when you arrive at your destination so I know you made it". A lot of times games will use interpolation in case of lag, dropped packets, etc. so UDP can still be utilized.

Here are some good articles that discusses everything in detail: https://gafferongames.com/tags/networking/

Here is one that discusses the TCP / UDP protocols: https://gafferongames.com/post/udp_vs_tcp/

Here is one that discusses the interpolation: https://gafferongames.com/post/snapshot_interpolation/

[edit]

In your case of text the interpolation would not work and you would need a guaranteed delivery. Otherwise, you may find that there is missing text in places, which wouldn't be desirable. What did you test exactly to know that there was too much delay?

3 hours ago, KKTHXBYE said:

So after checking that tcpip protocol doesn't fit my needs (to much delay)

How much delay are we talking about? Unless you happen to have a networking scenario that has a ridiculous degree of packet loss, almost all of that delay is likely to be software-side.

Have you experimented with enabling TCP_NODELAY to circumvent the default buffering behaviour?

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

To be honest, i didnt really want to show this thus its not a game at all, but the problem is related anyway to realtime networking so and maybe in future ill make a game knowing such things,

This is a test and not the thing i want that app to work (actually i want to view something from different projection and edit it along on other screen)

I noticed one thing - it lags a server too (phone on the right)

Then i realized i use blocking sockets, this is the main issue why its lagging so much, write and read functions (actually select for client socket) hold up a thread which holds up main thread from processing packets, and uploading to a thread commands it wants to send,

Basically even if i release a finger sometimes i need to wait even 10 seconds for client to actually receive all commands and thus it will insert a box on its app, but thats odd i have sent all commands from server to client and client processes like 512 bytes of data in 10 seconds.....  When select and read should return immideatly after knowing theres a data to read, anyway i read 256 per thread loop,

Maybe it has something to do with multithreaded layer i wrote that it works like that:

There is a class named desktop window manager ?

It contains client and server class and a list of windows along other virtual functions

But the main process of a frame that is run on thread looks like this

Thread2

Check whenever theres a data to be read

CmdsIn.Lock();

Add data to CmdsIn only if they are valid commands

CmdIn.Unlock();

Read data

CmdsOut.Lock();

Send to server all commands pending to be sent

CmdsOut.Unlock();

Now in main thread i am actually processing data

It contains a magic loop ? thus i think it aint that safe

    while (client->commands_received.Locked()) {}//block till nothing uses it

socket->CmdIn.Lock();
 

Then i read from CmdsIn

CmdIn.Unlock();

 

And so on in a thread2 i have the same

While (CmdIn.Locked) {} 

Before adding commands to cmdin

And while (cmdOut.Locked) {}

Before sending any pending commands

So main thread doesnt use this block of memory at the same time, thus i didnt check which of these two (read select or write) or while() loops are causing lag

 

And with tcp nodealy well it may look like its a bit faster but it aint realtime,

Even when i press a button this packet sometimes need to be received in processed in 1 to 2 seconds after other phone sends it, so somethings wrong and there are so much things to check,

However i dont know how to manage nonblocking sockets,

So i asked about udp cause blushogun said that they are for realtime networking

And acfually if i send a command which is 20 bytes long and it takes a second to process on other peer so thats definetky something way wrong with tcp protocol, (along with my implementatikn) not to mention multiplayer games that handle way more data at realtime

 

I really wanted to avoid this cause topic might be removed but well.......

Advertisement
1 hour ago, KKTHXBYE said:

I noticed one thing - it lags a server too (phone on the right)

Are you blocking the server command queue while you are sending commands out?  Or, is the server able to add commands at the "same time" (with thread safety) that commands are being sent without having to wait for the queue to be emptied?

Yeah they are blocked, if server sends commands then main thread waits to add any new ones, additionally server is managed in one thread (not main one) so if it receives any commands from client it adds them to cmdout list and sends them away

Its like read from clients

Lock

Send anything back to rrst of clients

Unlock

Then main thread can add something, this stays true for both server and client

Hope you get me

2 minutes ago, KKTHXBYE said:

Hope you get me

Yes, I completely understand.

3 minutes ago, KKTHXBYE said:

Yeah they are blocked, if server sends commands then main thread waits to add any new ones, additionally server is managed in one thread (not main one) so if it receives any commands from client it adds them to cmdout list and sends them away

That is most likely where your drawing latency is coming from.   Another approach for you would be to have the queue only be locked when a command is either pushed or popped off of it.  

** Warning: quickly created pseudocode follows...

So the creation of the command at the server would be (in its own thread):


while ( threadIsRunning )
{
    // I'm not sure of your command creating mechanisms, 
    // so, this could be a bit off-the-mark
    Command command = GetCreatedCommand();
    if ( command )
    {
        LockQueue();
        PushCommandOnQueue( command );
        UnlockQueue();
    }
}

 

And the sending of the command would be (in its own thread):


while ( communicationThreadIsRunning )
{
    LockQueue();
    Command command = PopOneCommandFromQueue(); // Could be null if nothing is in the queue
    UnlockQueue();

    if ( command )
    {
        SendCommand( command );
    }

    // Give up the thread so others have a chance to use the queue
    GiveUpTheThread();
}

 

This would alleviate some of the drawing latency on the server.  You might also see an improvement in the communication times because when the system is drawing it is not sending commands.  A similar mechanism could be utilized for received commands.

 

Thats exactly what im doing at this point. But will tcp be able to handle this realtime chat? I doubt.

This topic is closed to new replies.

Advertisement