some questions about udp

Started by
16 comments, last by hplus0603 14 years, 6 months ago
Hello again I am working on a multiplayer game project but I am not sure which one to use, tcp or udp it will probably work on lan, I am not planning to deal with big lags for now but maybe later. so my question is, is it possible that recieved data gets corrupted if I use udp? and even on LAN? what about lost or duplicated packages? I think I can deal with these problems, but if they are not necessary on lan, I will not work on it for now. also some questions about how udp works. I know very little about tcp, but I think udp will a bit different. Here is what I am planning. First server creates an udp socket and binds it. after client creates a socket for himself and uses sendto method to send an initial message. in this message, there will contain a port number that client binded so server can send messages back to client (server can gets the ip of the client from the recvfrom operation) is it ok? If not what should I do. It would be great if you can find a simple chat application using udp sockets, I couldn't find any =( edit: I am using winsocks and c++
taytay
Advertisement
oh nevermind the second part, I can just use the same socket in server with the address information that I get from recvfrom to send a reply
taytay
It's OK and should work fine.
You will never receive corrupted data, not even on the internet, but duplicated and lost packets are possible. On the internet it's to be expected, and on LAN it's still possible. It's extremely unlikely on a LAN though, so you can pretty much ignore it if you want to, you probably will never lose a packet while testing on your LAN.
If you don't have anything against using TCP it will often be fast enough (especially on LAN, where TCP will be as fast as UDP), but UDP can be easier sometimes.
In the long run you must deal with lost and duplicated packets for robust networking with UDP.
thank you for your answer.

another question =)


know I am using an example like that


server
while(1){  recvfrom(RecvSocket, RecvBuf,  BufLen,  0,  (SOCKADDR *)&SenderAddr, &SenderAddrSize);  printf("%s %s %d\n", RecvBuf, inet_ntoa(SenderAddr.sin_addr),   SenderAddr.sin_port);  sendto(RecvSocket, "hi", 3, 0, (SOCKADDR *)&SenderAddr, SenderAddrSize);}


client
while(1){  sendto(SendSocket, "Hello",  6,  0, (SOCKADDR *) &RecvAddr, sizeof(RecvAddr));  int s = sizeof(RecvAddr);  char test[32];  recvfrom(SendSocket, test, 32, 0, (SOCKADDR *)&RecvAddr,  &s);  printf("%s %s %d\n", test, inet_ntoa(RecvAddr.sin_addr), RecvAddr.sin_port);    system("pause");}


it works fine, for server it prints all the messages from all clients like

Hello 127.0.0.1 10001
Hello 127.0.0.1 10002
Hello 127.0.0.1 10003

and for clients same message

hi 127.0.0.1 10001

but is there a way for server to recieve message from a certain client? While using tcp, there was a socket for each client and I was simply using recv() method. should I check ip and port each time I get a message to determine which client is sending it?
taytay

Hello-

Quote:I am working on a multiplayer game project but I am not sure which one to use, tcp or udp


I really recommend UDP! The fact that it is connectionless is nice: it means occasional network glitches won't break your game. It does mean you have to be careful about managing connections yourself (deal with out-of-order or missing packets, keep data transmitted down to a size that will fit in a single packet, etc.). For most games, UDP is perfect, because you won't mind occasionally losing data.


Quote:oh nevermind the second part, I can just use the same socket in server with the address information that I get from recvfrom to send a reply


Yup, you get the sender's address information (ip and port) with every UDP packet you receive. You may want to use that information to stop spoofing (in case you are worried about player A pretending to send player B's packets).

-Thomas
Quote:Original post by shultays
but is there a way for server to recieve message from a certain client? While using tcp, there was a socket for each client and I was simply using recv() method. should I check ip and port each time I get a message to determine which client is sending it?

No, you can't get the next message of a certain client if you don't read the previous messages (if they all send to the same server-port).

Example:
Client A sends packet P1.
Client A sends packet P2.
Client B sends packet P3.

If you want to receive the packet P3 sent from client B, you have to receive P1 and P2 before.

What you can to ist just receive all packets and store them in a queue coresponding to the client which sent the packet.
Then if you want to check for a packet from a special client, just check it's queue.
-----The scheduled downtime is omitted cause of technical problems.
Quote:should I check ip and port each time I get a message to determine which client is sending it?


Yes. This, and all your other questions, are actually answered in the Forum FAQ. I highly recommend it!
enum Bool { True, False, FileNotFound };
thank you all guys!
taytay
Quote:Original post by Erik Rufelt
You will never receive corrupted data, not even on the internet, but duplicated and lost packets are possible. On the internet it's to be expected, and on LAN it's still possible. It's extremely unlikely on a LAN though, so you can pretty much ignore it if you want to, you probably will never lose a packet while testing on your LAN.
The downside is that actually testing your UDP code on a LAN can be difficult. A trick I use to to test my UDP code while running on a LAN is to flood the LAN with junk data - which will cause many of your legitimate packets to be lost. I find that netcat'ing /dev/zero between the test machines does a wonderful job [smile]

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


The complexity of your udp protocol will depend on the nature of your game.

If you are only sending positional updates which will always be superceded by updates sent after a short interval, you can simplify your mechanism to not care about missed packets (and use a simple sequence number in the packets to discard late/duplicate packets).

If your packet data load is small you can eliminate most of the effects of lost packets by piggybacking the data load of the previous packet on every new packet (send the load for time T-1 in the packet containing load for time T). That isnt perfect but it eliminates a significant number of lost packet cases.
If you send alot of data every cycle then this wont work as packet MTU is around 1490 bytes.

Unfortunately most games send critical 'must be delivered' information and thats where it starts getting complicated to get 'reliable' delivery of packets.
TCP has this inbuilt, but in UDP you would have to come up with your own mechanism (like packet queueing and sending Resend messages for missing packets
or a ACK every packet system with lots of endcases for when the ACK gets lost etc...)

You also would want some cleanup mechanism for your client connections so that if the client or server dies the other side will see a stoppage of traffic and if that goes past a threshold then its assumed the other side is gone (simply timestamp when the packet comes in for the connection and check the interval...)
--------------------------------------------[size="1"]Ratings are Opinion, not Fact

This topic is closed to new replies.

Advertisement