Quick UDP/TCP question

Started by
17 comments, last by Tree Penguin 18 years, 10 months ago
Quote:Original post by OrangyTang
TCP only does a checksum as well, so the possibility of getting corrupted data from both is roughly the same.


Right, so when you download a multi-megabyte archive via TCP and it fails the CRC check (or MD5 hash, etc.), you download it again. This happens frequently enough that large downloads are sometimes broken up into smaller files.

This raises another point: TCP data should also be validated with a CRC or stronger method.
Advertisement
Wow, thanks for all the replies.

First of all, i know about the fragmentation of large (a little over one KB iirc) datagrams. I also know that the order in which the datagrams are sent and recieved can be different because of different routes the packets can go. I also know that when datagrams are dropped (which can occur at anytime), the app isn't notified about this and that if the datagram gets fragmented (due to it's size) and one of the fragments isn't recieved the whole datagram is dropped.

What i really wanted to know is wether or not the initialization code is the same, i guess so now, as no-one really said anything about that.

Anyway, thanks everyone and thanks Washu for noting the sendto and recvfrom methods.

Cheers!
Quote:Original post by Tree Penguin
What i really wanted to know is wether or not the initialization code is the same, i guess so now, as no-one really said anything about that.


UDP:
s = ::socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);

TCP:
s = ::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
There's so much checking in the various layers that your data goes through, that the weakness of the UDP checksum, in practice, just doesn't matter. You should be concerned about hackers mal-forming packets, and making sure you deal correctly with those kinds of packets. If you deal well with those packets, then by inference, you'll deal well with all kinds of mal-formed packets, no matter what the cause.

I e: you can probably be sure that what you receive, is what the sender intended for you to receive. You can NOT, however, be sure that that sender is someone who has your best interests at heart. In fact, you should assume the reverse -- for every packet you receive.
enum Bool { True, False, FileNotFound };
Ok, thanks all. Still got one question though:

With TCP/IP you have a server and a client, the client connects to the server (which has opened a listening port). When connected the server can also send messages back to the client.

How is this properly done using UDP? I know it can be done when the client becomes a server (opens a listening port) of it's own but that would raise several issues when that client uses a router without a proper NAT configuration.

Should it be done in a different way or is there a way to solve the router problems?

Thanks in advance!
Typically a server is on a fixed IP address, and opens a UDP socket on a fixed predetermined port #.

The client opens up a UDP socket using any available port, and uses sendto() to send a message to the server. IP address and port the server is using are again predetermined as above and passed as parameters to sendto().

The server receives a packet using recvfrom(), which retrieves both the message and the IP/port the message came from. To reply, the server merely sends a message back using the IP/port it got from recvfrom().

It's extremely simple on the surface. A server can receive messages from literally hundreds of thousands of different senders at a time without the underlying transport layer having to do any management of them.

As for NAT routers, here's how I think they work -- I'm pretty sure this is what they do based on logical deduction. I haven't actually researched it, but I know they work and games do in fact play just fine over UDP/NAT, so this is logically how they must work:

All UDP packets have a source IP address and port of where they came from. When a NAT router sees a computer behind the NAT sending out a UDP packet to someone outside the NAT, the router will rewrite the UDP packet's headers so the intended recipient has a valid IP address to reply to. It also temporarily makes a mapping of the client's IP and port. When the router sees an incoming UDP packet destined for the internal network on the mapped IP/port, it forwards it to the client.

The router's UDP mapping is temporary and expires if no traffic flows over that port for an extended period of time.

Robert
A more detailed description of NAT can be found here (also linked from the Forum FAQ).
enum Bool { True, False, FileNotFound };
A UDP session is considered for NAT purposes, exactly like a TCP connection. Except it has no explicit start / end or any state, so the NAT router, just has to maintain the session NAT rules in place until some timeout period has expired.

Again, unlike TCP, in UDP, any packet can be the start of a session (there is no SYN flag) - the session-management is entirely application-specific.

As long as the client and server don't make any assumptions about the other one's apparent and local address being the same, it should work.

Basically the rule says, always send packets back from whence they (apparently) came, not anywhere else. The specific no-no, is sending IP addresses or port numbers inside data.

Mark
Ok, thanks, i know everything i need now.

This topic is closed to new replies.

Advertisement