As mentioned earlier in the chapter, there are two kinds of packets commonly used to transmit information on IP networks. The most common type, the TCP packet, is the right choice for nearly all cases because it ensures that the data arrives uncorrupted or else signals an error if there is a problem that cannot be corrected. The alternative, the UDP packet, is useful for real-time streaming applications. In such applications, if a packet arrives damaged, it does not matter whether the packet could be corrected or retransmitted, because there is no time to do so. The .NET Compact Framework supports the use of UDP packets. There are other packet types in use today, but only the most advanced network experts are likely to care about them, and they are academic to everyone else. Thus, they are beyond the nuts-and-bolts programming approach of this book. UDP packets differ from TCP packets in that they are connectionless , whereas the TCP protocol is a connection-oriented protocol, which means we need to connect a socket to a remote computer before we can start sending or receiving data using that socket. Connectionless protocols do not require any connection to be established before trying to send or receive data. If no one is listening to the IP address and port where a UDP packet is sent, then the packet is simply lost. The easiest way to work with UDP packets is by using the UdpClient class, which is supported in the .NET Compact Framework. The UdpClient class allows programmers to send bytes to a remote party. Also, the UdpClient lets developers receive bytes either from a specific remote party or from any party who tried to send data to the port on which the UdpClient listens. The interesting constructors and methods for using the UdpClient are as follows :
Writing Code for UdpClientThis sample code comes from the sample application from the next section, "Writing for the UdpClient: Sample Application." The code demonstrates how to set up a UdpClient that attempts to send UDP packets to a computer at IP address 192.168.0.200 , port 8758. Note that although there is a call to UdpClient.Connect() , this is merely a convenience. The UdpClient now knows where to send the UDP packets when UdpClient.Send() is called, but there is no persistent connection established, as there is with TCP packets. C# IPEndPoint senderIP = new IPEndPoint(IPAddress.Parse("192.168.0.200"), Convert.ToInt32(8758)); UdpClient l_UdpClient = new UdpClient(); l_UdpClient.Connect(senderIP); for (int i = 0; i < 20; i++) { l_UdpClient.Send(Encoding.ASCII.GetBytes("Hello_UDP_1"), Encoding.ASCII.GetBytes("Hello_UDP_1").Length); System.Threading.Thread.Sleep(1000); } l_UdpClient.Close(); VB Dim senderIP As System.Net.IPEndPoint senderIP = New System.Net.IPEndPoint(System.Net.IPAddress. Parse("192.168.0.200"), 8758)) Dim l_UdpClient As System.Net.Sockets.UdpClient l_UdpClient = New System.Net.Sockets.UdpClient l_UdpClient.Connect(senderIP) Dim i As Integer For i = 1 To 20 l_UdpClient.Send(System.Text.Encoding.ASCII.GetBytes ("Hello_UDP_1"), System.Text.Encoding.ASCII.GetBytes("Hello_UDP_1").Length) System.Threading.Thread.Sleep(1000) Next i l_UdpClient.Close() The following snippet of code creates a loop. Each iteration of the loop blocks and listens on port 8758 until it receives a UDP packet from any IP address. Note how this differs from standard TCP connections, where a persistent connection from a specific IP address must be established before data can be received. C# IPEndPoint listenerIP = new IPEndPoint(IPAddress.Any, 8758); UdpClient listener = new UdpClient(listenerIP); for (int i = 0; i < Convert.ToInt16(this.txtMaxPackets.Text); i++) { // Now receive the three datagrams from the listener IPEndPoint receivedIPInfo = new IPEndPoint(IPAddress.Any, 0); byte[] data = listener.Receive(ref receivedIPInfo); this.textBox1.Text += ("GOT: " + Encoding.ASCII.GetString(data, 0, data.Length) + " FROM: " + receivedIPInfo.ToString()); } VB Dim listenerIP As System.Net.IPEndPoint listenerIP = New System.Net.IPEndPoint(System.Net.IPAddress.Any, 8758) Dim listener As System.Net.Sockets.UdpClient listener = New System.Net.Sockets.UdpClient(listenerIP) Dim i As Integer For i = 1 To Convert.ToInt16(Me.txtMaxPackets.Text) ' Now receive the three datagrams from the listener Dim receivedIPInfo As System.Net.IPEndPoint receivedIPInfo = New System.Net.IPEndPoint(System.Net.IPAddress.Any, 0) Dim data As Byte() data = listener.Receive(receivedIPInfo) Me.textBox1.Text += ("GOT: " + System.Text.Encoding.ASCII.GetString(data, 0, data.Length) + " FROM: " + receivedIPInfo.ToString()) Next i The same tricks for converting fundamental data types to and from byte arrays that were discussed in the section "Reading and Writing with a Connected Socket" are also useful when dealing with the UdpClient. Writing for the UdpClient : Sample ApplicationThe UDPHello sample application is composed of two separate programs. The first, UDPHelloServer , broadcasts simple UDP packets in a loop to a specified IP address and port. Because of the connectionless nature of UDP packets, there is no exception if no one is listening at the other end or if the packets are refused . The second program, UDPHelloClient , listens on port 8758 for UDP packets broadcast from any source. After each UDP packet is received, the IPEndPoint named receivedIPInfo is populated with the IP address and port number of the source of the UDP packet. The contents of each packet received and the information in receivedIPInfo are painted into a TextBox. The source code for UDPHelloClient is in SampleApplications\Chapter5\UDPHelloClient_CSharp and SampleApplications\Chapter5\UDPHelloClient_VB . The source code for UDPHelloServer is in SampleApplications\Chapter5\UDPHellpServer_CSharp and SampleApplications\Chapter5\ UDPHelloServer_VB . |