Feb. 28, 2009, 11:22 p.m.
posted by vendetta
Distinguishing UDP Messages
One of the best features of UDP is that it addresses the TCP difficulty of handling messages without honoring their boundaries. UDP preserves the message boundaries of all sent messages. Each ReceiveFrom() method call will read only the data sent as a result of a single SendTo() method call.
Recall that a UDP socket, once it’s created, can receive messages from any UDP client. For the UDP socket to distinguish which client sent which data, it is imperative that each message be self-contained in a single packet and marked with the sending device’s IP information. This allows the receiving device to identify both message and sender.
The programming for setting this up is demonstrated in the next two programs. The TestUdpClient.cs program sends multiple messages to the server, while the TestUdpSrvr.cs program attempts to read each message individually (similar to the failed TCP message test in the preceding chapter). First, let’s examine TestUdpSrvr.cs in Listing 6.4.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class TestUdpSrvr
{
public static void Main()
{
int recv;
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050);
Socket newsock = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
newsock.Bind(ipep);
Console.WriteLine("Waiting for a client...");
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tmpRemote = (EndPoint)(sender);
recv = newsock.ReceiveFrom(data, ref tmpRemote);
Console.WriteLine("Message received from {0}:", tmpRemote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
string welcome = "Welcome to my test server";
data = Encoding.ASCII.GetBytes(welcome);
newsock.SendTo(data, data.Length, SocketFlags.None, tmpRemote);
for(int i = 0; i < 5; i++)
{
data = new byte[1024];
recv = newsock.ReceiveFrom(data, ref tmpRemote);
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
}
newsock.Close();
}
}
TestUdpSrvr binds a UDP socket to the 9050 port and waits for a client to connect with a greeting message. When this happens, the server sends back a welcome banner and then attempts to receive five messages in a row from the client.
| Note |
One nice feature of this server program is that the application protocol specifies that after five messages the client should close its socket, so the server can likewise close its socket. |
Now take a look at the TestUdpClient.cs program (Listing 6.5), which demonstrates the sending of multiple UDP messages to the server.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
class TestUdpClient
{
public static void Main()
{
byte[] data = new byte[1024];
IPEndPoint ipep = new IPEndPoint(
IPAddress.Parse("127.0.0.1"), 9050);
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
string welcome = "Hello, are you there?";
data = Encoding.ASCII.GetBytes(welcome);
server.SendTo(data, data.Length, SocketFlags.None, ipep);
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint tmpRemote = (EndPoint)sender;
data = new byte[1024];
int recv = server.ReceiveFrom(data, ref tmpRemote);
Console.WriteLine("Message received from {0}:", tmpRemote.ToString());
Console.WriteLine(Encoding.ASCII.GetString(data, 0, recv));
server.SendTo(Encoding.ASCII.GetBytes("message 1"), tmpRemote);
server.SendTo(Encoding.ASCII.GetBytes("message 2"), tmpRemote);
server.SendTo(Encoding.ASCII.GetBytes("message 3"), tmpRemote);
server.SendTo(Encoding.ASCII.GetBytes("message 4"), tmpRemote);
server.SendTo(Encoding.ASCII.GetBytes("message 5"), tmpRemote);
Console.WriteLine("Stopping client");
server.Close();
}
}
The TestUdpClient program sends its greeting message to the designated server, then receives the welcome banner from the server. After it receives the welcome banner, it sends five messages in a row to the server and closes the socket.
If possible, try testing these programs on a network. When you run the test, you will see that each message is received the same way that it was sent—the UDP subsystem is guaranteed to maintain the message boundaries. You may have noticed, however, depending on your network, that some of the messages are missing. This is indicative of one of disadvantages of UDP communications. Although the messages are guaranteed to remain intact, they are not guaranteed to be delivered. The next section describes this and other problems inherent with UDP communications.