What is the minimum-size UDP packet?

D

David Sworder

Hi,

I'm writing an application in which a client (C#/WinForms) and server
(C#/service) interact with one another. The client establishes a "session"
with the server but for scalability reasons there is not a one to one map
between a session and a physical TCP connection. A client may disconnect the
TCP connection if it is idle for more than 60 seconds... yet a conceptual
"session" may last for days at a time.

It's necessary that the server keep track of all open sessions. The way
I'm planning to handle this is to have the client send it's session ID
[which is 4 bytes long] to the server every 2 minutes via UDP. The server
will respond via UDP with a one bit (datatype='bit') reply of either yes or
no. If the server hasn't received a valid session ID via UDP from the client
in over 10 minutes, the server will assume that the client is gone and will
close out the "session."

With that as the background, here are my questions:

1) I understand that UDP is a best-effort protocol and delivery of the
packets is not guaranteed. My system can tolerate that. What it *can't*
tolerate is only "part" of the client's UDP notification making it across
the wire. Recall that the client's UDP notification is 4 bytes long. I can't
tolerate a situation in which only 2 bytes get through [without the server
being made aware that some sort of error has occurred via a Winsock
exception]. It should be 4 bytes or none at all. Is UDP suitable for my
needs?

2) Is there a "minimum packet size" for UDP? In other words, when my
client sends a payload of 4 bytes to the server, are there actually more
bytes going across the wire due to a minimum packet size? I'm not too
up-to-speed on TCP/IP, but I know that there is something called a minimum
transmission unit (MTU) which can be set as high as 1,500 bytes or so. Will
my 4-byte notification be "padded" with 1,496 extra bytes? It's very
important that I get an answer to this question because my app needs to
conserve bandwidth [I may have 1000's of simultaneous "sessions" at any
given time].

Thanks in advance for any help you can provide!
 
?

_

David,
1) I understand that UDP is a best-effort protocol and delivery of the
packets is not guaranteed. My system can tolerate that. What it *can't*
tolerate is only "part" of the client's UDP notification making it across
the wire.

Stay under the MTU and you will either see the entire packet or none of it.
2) Is there a "minimum packet size" for UDP? In other words, when my
client sends a payload of 4 bytes to the server, are there actually more
bytes going across the wire due to a minimum packet size?

No - there is some overhead associated with the packet but there is no _minimum_
size (uh, actually I haven't tried sending zero bytes <g>).
 
T

Trevor

David Sworder said:
Hi,

I'm writing an application in which a client (C#/WinForms) and server
(C#/service) interact with one another. The client establishes a "session"
with the server but for scalability reasons there is not a one to one map
between a session and a physical TCP connection. A client may disconnect the
TCP connection if it is idle for more than 60 seconds... yet a conceptual
"session" may last for days at a time.

It's necessary that the server keep track of all open sessions. The way
I'm planning to handle this is to have the client send it's session ID
[which is 4 bytes long] to the server every 2 minutes via UDP. The server
will respond via UDP with a one bit (datatype='bit') reply of either yes or
no. If the server hasn't received a valid session ID via UDP from the client
in over 10 minutes, the server will assume that the client is gone and will
close out the "session."

With that as the background, here are my questions:

1) I understand that UDP is a best-effort protocol and delivery of the
packets is not guaranteed. My system can tolerate that. What it *can't*
tolerate is only "part" of the client's UDP notification making it across
the wire. Recall that the client's UDP notification is 4 bytes long. I can't
tolerate a situation in which only 2 bytes get through [without the server
being made aware that some sort of error has occurred via a Winsock
exception]. It should be 4 bytes or none at all. Is UDP suitable for my
needs?

2) Is there a "minimum packet size" for UDP? In other words, when my
client sends a payload of 4 bytes to the server, are there actually more
bytes going across the wire due to a minimum packet size? I'm not too
up-to-speed on TCP/IP, but I know that there is something called a minimum
transmission unit (MTU) which can be set as high as 1,500 bytes or so. Will
my 4-byte notification be "padded" with 1,496 extra bytes? It's very
important that I get an answer to this question because my app needs to
conserve bandwidth [I may have 1000's of simultaneous "sessions" at any
given time].

Thanks in advance for any help you can provide!

--
Sincerely,

David Sworder
http://www.CodeFanatic.com
David,

1) You will get either all or none of the datagram. Is UDP for you? I will
list some pro/cons of each TCP & UDP and let you decide.

UDP:
Connectionless - there is no connection. "sessions" are frequently used to
simulate a connection. Since there is no connection, you don't know when it
is broken (other end disconnects). The host typically removes a client when
it hasn't received some sort of pulse (in your case, session ID) datagram.
This can happen some time after the other device actually shuts off, which
may be good or bad for you.

Less overhead than TCP - datagrams are sent once, either they make it or
they don't make it.

Packet based - you are dealing with datagrams (packets).

TCP:
Connection based - both ends know when the peer has broken the connection

More overhead than UDP - frames (packets for TCP) will be resent if the
other side does not acknowledge them. This is less efficient than UDP, but
when you build ACK/retries/order into UDP they end up at about the same
efficiency level.

Stream based - you are dealing with a continious stream of data. You can
treat the stream like packets but it is not really the idea.

Those are the strong points. There are tons of arguments favoring each
protocol on the internet if you are looking for more information.

2) The minimum datagram size is 1 byte. MTU means MAXIMUM transmit unit,
not minimum. For a UDP packet, the Winsock stack will send across another
20 bytes (12 for IP header, 8 for UDP header) over the wire. These 20 bytes
are the UDP/IP headers which are required, they are not pad bytes. 1500 is
the "standard" MTU for UDP datagrams. I get best results when I set my MTU
to 512. YMMV.

Of course, this is all just my 0.02.
 
D

David Sworder

Thanks Zane and Trevor...

That's great information. Given the large overhead (relatively speaking,
given my small payload size) of UDP, I'm wondering if it might be better to
just keep the TCP connection in place at all times. I imagine this would
eliminate the need for keepalives. The downside is that the server could be
maintaining 1000's of idle connections at any given time. Here's another
somewhat related question:

Let's say that the client and server have a TCP connection in place. The
client then unplugs his network cord [or takes some other action to
abnormally disconnect his computer without the server receiving a TCP/IP
notification that the connection has closed]. How long will it take before
my server realizes that the connection is dead? Does TCP/IP have it's own
mechanism of testing for downed connections?
 
T

Trevor

David,

See inline...

David Sworder said:
Thanks Zane and Trevor...

That's great information. Given the large overhead (relatively speaking,
given my small payload size) of UDP, I'm wondering if it might be better to
just keep the TCP connection in place at all times. I imagine this would
eliminate the need for keepalives. The downside is that the server could be
maintaining 1000's of idle connections at any given time. Here's another
somewhat related question:

I didn't mention in my other post that I have developed two systems (1 for
TCP, 1 for UDP) identical to the one you are developing. I use sessions on
top of TCP for my TCP implementation. By sessions, I mean basically I send
a login packet (user/password) and then the host will start sending data to
me that is destined to that username. You should really consider making the
TCP server multi-threaded if you haven't done so. I chose to have one
thread for listening, 1 thread for all of the clients (it traverses a vector
of clients, sending/receieving for each client as needed).
Let's say that the client and server have a TCP connection in place. The
client then unplugs his network cord [or takes some other action to
abnormally disconnect his computer without the server receiving a TCP/IP
notification that the connection has closed]. How long will it take before
my server realizes that the connection is dead? Does TCP/IP have it's own
mechanism of testing for downed connections?

I don't know about .NET, but the native API recv() will tell you right away
if the client disconnected (without needing to receive data). Java would
throw an IOException the next time you try to read/write to a broken socket.
I am sure .NET works like the Java implementation. Even if the .NET version
does not work like this, it is possible to make one that does.
 
W

William Stacey [MVP]

TCP server multi-threaded if you haven't done so. I chose to have one
thread for listening, 1 thread for all of the clients (it traverses a vector
of clients, sending/receieving for each client as needed).

Cool. Whats a vector? An arraylist? Does that thread just keep looping on
the list to find some work in a slot or does it block on some event(s)? TIA
 
S

Stephanie Song [MSFT]

Answers to the questions below then some general answer from previous
questions

1) If no data is being sent between a client and a server, TCP as a protocol
has keepalive mechanims to verify the connection is still alive; however,
this is not turned on by default in Windows. If the peer dies in a way the
remote endpoint doesn't receive any information, the connection will just
sit there in the default setting. If you try to send data on this connection
then it can be detected the peer has died and you will receive notification
but if you don't then you won't know if it is active or not. However, you
can enabled keepalive with setsockopt().

2) MTU stands for maximum transmission unit and controls how many bytes can
be sent in each frame on a certain link. The minimum size you are thinking
of may be the minimum required on the physical link - for example, ethernet
frames have a minimum size and the network card will pad the frame to meet
the size requirement so collisions on the wire can be detected. Protocols
using the link do not have to worry about this and neither do you.

3) UDP packets can contain no bytes. Because UDP is a packetized protocol
sending 0 bytes is acceptable; if you try to do this in TCP, which is a
stream protocol, then nothing will go on the wire.


Stephanie
 
T

Trevor

William,

Yes, a vector is similar to an ArrayList. The thread uses
WaitForMultipleObjects and blocks for Winsock & file system events.
 
D

David Sworder

I didn't mention in my other post that I have developed two systems (1 for
TCP, 1 for UDP) identical to the one you are developing. I use sessions on
top of TCP for my TCP implementation. By sessions, I mean basically I send
a login packet (user/password) and then the host will start sending data to
me that is destined to that username. You should really consider making the
TCP server multi-threaded if you haven't done so. I chose to have one
thread for listening, 1 thread for all of the clients (it traverses a vector
of clients, sending/receieving for each client as needed).

I do have 1 thread for listening as you do, but I handle incoming data
using the thread pool. As soon as a connection is accepted, I do a
BeginReceive() against the newly accepted socket. BeginReceive() returns
immediately. A thread from the thread pool will wake up when data is
received and the appropriate processing takes place. The thread pool
optimizes how many running threads from its pool are in use at any given
time, but from what I understand it tries to make the number of running
threads match the number of CPUs in the machine. So since I'm running on a
dual processor machine, even if there are 1000 simultaneous connections, I
typically won't have more than two threads receiving data at the same
time... at least this is my understanding of how this approach is supposed
to work. The goal is to keep the CPUs busy and keep the number of threads
low to avoid a context switching penalty. If, while processing data, one of
my thread-pool threads enters a blocking state [i.e perhaps to connect to a
database], the thread pool senses that a thread is blocked and automatically
frees up another thread to receive more data from another one of the
connections... kind of a neat approach. I read about it in MSDN.


David
 
D

David Sworder

Hi Stephanie,

Thanks for your reply. See inline...
1) If no data is being sent between a client and a server, TCP as a protocol
has keepalive mechanims to verify the connection is still alive; however,
this is not turned on by default in Windows. If the peer dies in a way the
remote endpoint doesn't receive any information, the connection will just
sit there in the default setting. If you try to send data on this connection
then it can be detected the peer has died and you will receive notification
but if you don't then you won't know if it is active or not. However, you
can enabled keepalive with setsockopt().

How often is the keepalive packet sent across the wire?
2) MTU stands for maximum transmission unit and controls how many bytes can
be sent in each frame on a certain link. The minimum size you are thinking
of may be the minimum required on the physical link - for example, ethernet
frames have a minimum size and the network card will pad the frame to meet
the size requirement so collisions on the wire can be detected. Protocols
using the link do not have to worry about this and neither do you.

I think you're right. I'm thinking of the minimum size required on the
physical link. Here's my concern: I get charged based on how much bandwidth
I use. Bandwidth is monitored by a router at a colocation facility which
looks at how much data I pass over their network. If I sent 5 bytes of data
via UPD and the minimum transmission size for Ethernet is 1500 bytes, won't
my NIC wrap by 5 byte payload in 1500 bytes? And won't that router that is
monitoring my useage charge me for 1500 bytes? Perhaps that's something that
I should ask Verio, but hopefully you see what I'm getting at.
 
W

William Stacey [MVP]

Thanks Trevor. You can use WFMO to wait on socket handle? Or do you need
SOWait? If you would be so kind, could you walk me down a 1-2-3 list of
what happens in pseudo style or whatever is quick for you. TIA!
 
S

Stephanie Song [MSFT]

1) default time to sending first keepalive is 2 hours. The interval between
sending keepalive is at a default of 1s and after 5 retransmits without a
response the connection is considered dead. I suggest you read RFC 1122
section 4.2.3.6 for some considerations in using this option.

2) the minimum ethernet frame size is only 46 bytes. It looks as follows
[Preamble(7b)][Start Frame Delimiter(1b)][Dest Mac Addr(6b)][Source Mac
Addr(6b)][Length(2b)][Client Data (?b)][Pad (?b)][Frame Check Seq (4b)]
Since you are sending a UDP packet the "Client Data" field will contain
an IP packet with UDP embedded. An IP header with no options is 20 bytes
long, a UDP header is 8 bytes long, data is 5 bytes long. The UDP datagram
is going to be 13bytes long, the IP packet will be a minimum of 33 bytes
long and the ethernet frame will come out to 59 bytes. The padding will not
even need to be used in this case.
You can look up the header formats for the various protocols I indicated
above on the web if what I said isn't very clear.
 
D

David Sworder

You can look up the header formats for the various protocols I
indicated
above on the web if what I said isn't very clear.

It's very clear. Thanks Stephanie, you're awesome.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top