23.7. Connectionless Client/Server Interaction with DatagramsSo far, we have discussed connection-oriented, streams-based transmissions using the TCP protocol to ensure that the packets of data are transmitted reliably. Now we consider connectionless transmission using datagrams and UDP. Connectionless transmission via datagrams resembles the method by which the postal service carries and delivers mail. Information is bundled and sent in packets called datagrams, which can be thought of as similar to letters sent through the mail. If a large message will not fit in one envelope, it is broken into separate message pieces and placed in separate, sequentially numbered envelopes. All the envelopes are mailed at once. They may arrive in order, out of order or not at all. The person at the receiving end reassembles the message pieces in sequential order before attempting to interpret the message. If the message is small enough to fit in one envelope, the sequencing problem is eliminated, but it is still possible that the message will never arrive. (Unlike with postal mail, duplicate datagrams could reach receiving computers.) .NET provides the UdpClient class for connectionless transmission. Like TcpListener and TcpClient, UdpClient uses methods from class Socket. UdpClient method Send transmits data with Socket's SendTo method, and UdpClient method Receive reads data with Socket's ReceiveFrom method. The programs in Fig. 23.3 and Fig. 23.4 use datagrams to send packets of information between client and server applications. In the PacketClient application, the user types a message into a TextBox and presses Enter. The client converts the message to a Byte array and sends it to the server. The server receives the packet and displays the packet's information, then echoes, or returns, the packet to the client. When the client receives the packet, the client displays the packet's information. In this example, classes FrmPacket-Client and FrmPacketServer are implemented similarly. Figure 23.3. Server-side portion of connectionless client/server computing.
Figure 23.4. Client portion of connectionless client/server computing.
FrmPacketServer ClassFigure 23.3 defines class FrmPacketServer. Line 16 in the Load event handler for class FrmPacketServer creates an instance of the UdpClient class that receives data at port number 50000. This initializes the underlying Socket for communications. Line 17 creates an instance of class IPEndPoint to hold the IP address and port number of the client(s) that transmit to FrmPacketServer. The first argument to the IPEndPoint constructor is an IPAddress object; the second argument is the port number of the endpoint. These values are both 0, because we need only instantiate an empty IPEndPoint object. The IP addresses and port numbers of clients are copied into the IPEndPoint when datagrams are received from clients. Lines 3449 define DisplayDelegate and DisplayMessage, allowing any thread to modify txtdisplay's Text property. FrmPacketServer method WaitForPackets (lines 5266) executes an infinite loop while waiting for data to arrive at the FrmPacketServer. When information arrives, UdpClient method Receive (line 55) receives a Byte array from the client. We pass to Receive the IPEndPoint object created in the constructorthis provides the method with an IPEndPoint to which the program copies the client's IP address and port number. Lines 5659 display the packet's information and content in FrmPacketServer's TextBox. Line 63 echoes the data back to the client, using UdpClient method Send. This version of Send takes three argumentsthe Byte array to send, the array's length and the IPEndPoint to which to send the data. We use array data returned by method Receive as the data, the length of array data as the length and the IPEndPoint passed to method Receive as the data's destination. The IP address and port number of the client that sent the data are stored in receivePoint, so passing receivePoint to Send allows FrmPacket-Server to respond to the client. FrmPacketClient ClassClass FrmPacketClient (Fig. 23.4) works similarly to class FrmPacketServer, except that the client sends packets only when the user types a message in a TextBox and presses the Enter key. When this occurs, the program calls event handler txtInput_KeyDown (lines 5169). Line 62 converts the String that the user entered in the TextBox to a Byte array. Line 65 calls UdpClient method Send to send the Byte array to the FrmPacketServer that is located on localhost (i.e., the same machine). We specify the port as 50000, which we know to be FrmPacketServer's port. Lines 3348 define DisplayDelegate and DisplayMessage, allowing any thread to modify txtdisplay's Text property. Line 17 instantiates a UdpClient object to receive packets at port 50001we choose port 50001 because the FrmPacketServer already occupies port 50000. Method WaitFor-Packets of class FrmPacketClient (lines 7283) uses an infinite loop to wait for these packets. UdpClient method Receive blocks until a packet of data is received (line 75). The blocking performed by method Receive does not prevent class FrmPacketClient from performing other services (e.g., handling user input), because a separate thread (line 18) runs method WaitForPackets. When a packet arrives, lines 7881 display its contents in the TextBox. The user can type information in FrmPacketClient's TextBox and press the Enter key at any time, even while a packet is being received. The event handler for the TextBox processes the event and sends the data to the server. |