Connectionless Client/Server Interaction with Datagrams

Connectionless Client Server Interaction with Datagrams

Up to this point, 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. Connectionless transmission bundles and sends information in packets called datagrams, which can be thought of as similar to letters you send through the mail. If a large message will not fit in one envelope, that message is broken into separate message pieces and placed in separate, sequentially numbered envelopes. All the letters are mailed at once. The letters might 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 of datagrams could reach receiving computers.) C# provides the UdpClient class for connectionless transmission. Like TcpListener and TcpClient, UdpClient uses methods from class Socket. The UdpClient methods Send and Receive transmit data with Socket's SendTo method and read data with Socket's ReceiveFrom method, respectively.

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, the implementations of the PacketClientForm and PacketServerForm classes are similar.

Figure 23.3. Server-side portion of connectionless client/server computing.

(This item is displayed on pages 1248 - 1249 in the print version)

 1 // Fig. 23.3: PacketServer.cs
 2 // Set up a server that will receive packets from a
 3 // client and send the packets back to the client.
 4 using System;
 5 using System.Windows.Forms;
 6 using System.Net; 
 7 using System.Net.Sockets;
 8 using System.Threading; 
 9
10 public partial class PacketServerForm : Form
11 {
12 public PacketServerForm()
13 {
14 InitializeComponent();
15 } // end constructor
16
17 private UdpClient client; 
18 private IPEndPoint receivePoint;
19
20 // initialize variables and thread for receiving packets
21 private void PacketServerForm_Load( object sender, EventArgs e )
22 {
23 client = new UdpClient( 50000 ); 
24 receivePoint = new IPEndPoint( new IPAddress( 0 ), 0 );
25 Thread readThread = 
26  new Thread( new ThreadStart( WaitForPackets ) ); 
27 readThread.Start(); 
28 } // end method PacketServerForm_Load
29
30 // shut down the server
31 private void PacketServerForm_FormClosing( object sender,
32 FormClosingEventArgs e )
33 {
34 System.Environment.Exit( System.Environment.ExitCode );
35 } // end method PacketServerForm_FormClosing
36
37 // delegate that allows method DisplayMessage to be called
38 // in the thread that creates and maintains the GUI
39 private delegate void DisplayDelegate( string message );
40
41 // method DisplayMessage sets displayTextBox's Text property
42 // in a thread-safe manner
43 private void DisplayMessage( string message )
44 {
45 // if modifying displayTextBox is not thread safe 46 if ( displayTextBox.InvokeRequired ) 47 { 48 // use inherited method Invoke to execute DisplayMessage 49 // via a delegate 50 Invoke( new DisplayDelegate( DisplayMessage ), 51 new object[] { message } ); 52 } // end if 53 else // OK to modify displayTextBox in current thread 54 displayTextBox.Text += message; 55 } // end method DisplayMessage 56 57 // wait for a packet to arrive 58 public void WaitForPackets() 59 { 60 while ( true ) 61 { 62 // set up packet 63 byte[] data = client.Receive( ref receivePoint ); 64 DisplayMessage( " Packet received:" + 65 " Length: " + data.Length + 66 " Containing: " + 67 System.Text.Encoding.ASCII.GetString( data ) ); 68 69 // echo information from packet back to client 70 DisplayMessage( " Echo data back to client..." ); 71 client.Send( data, data.Length, receivePoint ); 72 DisplayMessage( " Packet sent " ); 73 } // end while 74 } // end method WaitForPackets 75 } // end class PacketServerForm

Figure 23.4. Client portion of connectionless client/server computing.

(This item is displayed on pages 1250 - 1252 in the print version)

 1 // Fig. 23.4: PacketClient.cs
 2 // Set up a client that sends packets to a server and receives
 3 // packets from a server.
 4 using System;
 5 using System.Windows.Forms;
 6 using System.Net; 
 7 using System.Net.Sockets;
 8 using System.Threading; 
 9
10 public partial class PacketClientForm : Form
11 {
12 public PacketClientForm()
13 {
14 InitializeComponent();
15 } // end constructor
16
17 private UdpClient client; 18 private IPEndPoint receivePoint; 19 20 // initialize variables and thread for receiving packets 21 private void PacketClientForm_Load( object sender, EventArgs e ) 22 { 23 receivePoint = new IPEndPoint( new IPAddress( 0 ), 0 ); 24 client = new UdpClient( 50001 ); 25 Thread thread = 26 new Thread( new ThreadStart( WaitForPackets ) ); 27 thread.Start(); 28 } // end method PacketClientForm_Load 29 30 // shut down the client 31 private void PacketClientForm_FormClosing( object sender, 32 FormClosingEventArgs e ) 33 { 34 System.Environment.Exit( System.Environment.ExitCode ); 35 } // end method PacketClientForm_FormClosing 36 37 // delegate that allows method DisplayMessage to be called 38 // in the thread that creates and maintains the GUI 39 private delegate void DisplayDelegate( string message ); 40 41 // method DisplayMessage sets displayTextBox's Text property 42 // in a thread-safe manner 43 private void DisplayMessage( string message ) 44 { 45 // if modifying displayTextBox is not thread safe 46 if ( displayTextBox.InvokeRequired ) 47 { 48 // use inherited method Invoke to execute DisplayMessage 49 // via a delegate 50 Invoke( new DisplayDelegate( DisplayMessage ), 51 new object[] { message } ); 52 } // end if 53 else // OK to modify displayTextBox in current thread 54 displayTextBox.Text += message; 55 } // end method DisplayMessage 56 57 // send a packet 58 private void inputTextBox_KeyDown( object sender, KeyEventArgs e ) 59 { 60 if ( e.KeyCode == Keys.Enter ) 61 { 62 // create packet (datagram) as string 63 string packet = inputTextBox.Text; 64 displayTextBox.Text += 65 " Sending packet containing: " + packet; 66 67 // convert packet to byte array 68 byte[] data = System.Text.Encoding.ASCII.GetBytes( packet ); 69 70 // send packet to server on port 50000 71 client.Send( data, data.Length, "127.0.0.1", 50000 ); 72 displayTextBox.Text += " Packet sent "; 73 inputTextBox.Clear(); 74 } // end if 75 } // end method inputTextBox_KeyDown 76 77 // wait for packets to arrive 78 public void WaitForPackets() 79 { 80 while ( true ) 81 { 82 // receive byte array from server 83 byte[] data = client.Receive( ref receivePoint ); 84 85 // output packet data to TextBox 86 DisplayMessage( " Packet received:" + 87 " Length: " + data.Length + " Containing: " + 88 System.Text.Encoding.ASCII.GetString( data ) + " " ); 89 } // end while 90 } // end method WaitForPackets 91 } // end class PacketClientForm

(a) Packet Client window before sending a packet to the server

(b) Packet Client window after sending a packet to the server and receiving it back

PacketServerForm Class

The code in Fig. 23.3 defines the PacketServerForm for this application. Line 23 in the Load event handler for class PacketServerForm creates an instance of the UdpClient class that receives data at port 50000. This initializes the underlying Socket for communications. Line 24 creates an instance of class IPEndPoint to hold the IP address and port number of the client(s) that transmit to PacketServerForm. 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 3955 define DisplayDelegate and DisplayMessage, allowing any thread to modify displayTextBox's Text property.

PacketServerForm method WaitForPackets (lines 5874) executes an infinite loop while waiting for data to arrive at the PacketServerForm. When information arrives, UdpClient method Receive (line 63) 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. This program will compile and run without an exception even if the reference to the IPEndPoint object is null, because method Receive initializes the IPEndPoint if it is null.

Lines 6467 update the PacketServerForm's display to include the packet's information and content. Line 71 echoes the data back to the client, using UdpClient method Send. This version of Send takes three argumentsthe byte array to send, an int representing 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 merely passing receivePoint to Send allows PacketServerForm to respond to the client.

PacketClientForm Class

Class PacketClientForm (Fig. 23.4) works similarly to class PacketServerForm, except that the Client object 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 inputTextBox_KeyDown (lines 5875). Line 68 converts the string that the user entered in the TextBox to a byte array. Line 71 calls UdpClient method Send to send the byte array to the PacketServerForm that is located on localhost (i.e., the same machine). We specify the port as 50000, which we know to be PacketServerForm's port.

Lines 3955 define DisplayDelegate and DisplayMessage, allowing any thread to modify displayTextBox's Text property.

Line 24 instantiates a UdpClient object to receive packets at port 50001we choose port 50001 because the PacketServerForm already occupies port 50000. Method WaiForPackets of class PacketClientForm (lines 7890) uses an infinite loop to wait for these packets. UdpClient method Receive blocks until a packet of data is received (line 83). The blocking performed by method Receive does not prevent class PacketClientForm from performing other services (e.g., handling user input), because a separate thread runs method WaitForPackets.

When a packet arrives, lines 8688 display its contents in the TextBox. The user can type information in the PacketClientForm window'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.

Client Server Tic Tac Toe Using a Multithreaded Server

Preface

Index

    Introduction to Computers, the Internet and Visual C#

    Introduction to the Visual C# 2005 Express Edition IDE

    Introduction to C# Applications

    Introduction to Classes and Objects

    Control Statements: Part 1

    Control Statements: Part 2

    Methods: A Deeper Look

    Arrays

    Classes and Objects: A Deeper Look

    Object-Oriented Programming: Inheritance

    Polymorphism, Interfaces & Operator Overloading

    Exception Handling

    Graphical User Interface Concepts: Part 1

    Graphical User Interface Concepts: Part 2

    Multithreading

    Strings, Characters and Regular Expressions

    Graphics and Multimedia

    Files and Streams

    Extensible Markup Language (XML)

    Database, SQL and ADO.NET

    ASP.NET 2.0, Web Forms and Web Controls

    Web Services

    Networking: Streams-Based Sockets and Datagrams

    Searching and Sorting

    Data Structures

    Generics

    Collections

    Appendix A. Operator Precedence Chart

    Appendix B. Number Systems

    Appendix C. Using the Visual Studio 2005 Debugger

    Appendix D. ASCII Character Set

    Appendix E. Unicode®

    Appendix F. Introduction to XHTML: Part 1

    Appendix G. Introduction to XHTML: Part 2

    Appendix H. HTML/XHTML Special Characters

    Appendix I. HTML/XHTML Colors

    Appendix J. ATM Case Study Code

    Appendix K. UML 2: Additional Diagram Types

    Appendix L. Simple Types

    Index



    Visual C# How to Program
    Visual C# 2005 How to Program (2nd Edition)
    ISBN: 0131525239
    EAN: 2147483647
    Year: 2004
    Pages: 600

    Flylib.com © 2008-2020.
    If you may any questions please contact us: flylib@qtcs.net