Connectionless Client/Server Interaction with Datagrams

Connectionless Client Server Interaction with Datagrams

We have been discussing connection-oriented, streams-based transmission. Now we consider connectionless transmission with datagrams.

Connection-oriented transmission is like the telephone system in which you dial and are given a connection to the telephone of the person with whom you wish to communicate. The connection is maintained for the duration of your phone call, even when you are not talking.

Connectionless transmission with datagrams is more like the way mail is carried via the postal service. If a large message will not fit in one envelope, you break it into separate message pieces that you place in separate, sequentially numbered envelopes. Each of the letters is then mailed at the same time. The letters could arrive in order, out of order or not at all (the last case is rare, but it does happen). The person at the receiving end reassembles the message pieces into sequential order before attempting to make sense of the message. If your message is small enough to fit in one envelope, you need not worry about the "out-of-sequence" problem, but it is still possible that your message might not arrive. One difference between datagrams and postal mail is that duplicates of datagrams can arrive at the receiving computer.

Figure 24.9Fig. 24.12 use datagrams to send packets of information via the User Datagram Protocol (UDP) between a client application and a server application. In the Client application (Fig. 24.11), the user types a message into a textfield and presses Enter. The program converts the message into a byte array and places it in a datagram packet that is sent to the server. The Server (Fig. 24.9) receives the packet and displays the information in it, then echoes the packet back to the client. Upon receiving the packet, the client displays the information it contains.

Figure 24.9. Server side of connectionless client/server computing with datagrams.

(This item is displayed on pages 1132 - 1134 in the print version)

 1 // Fig. 24.9: Server.java
 2 // Server that receives and sends packets from/to a client.
 3 import java.io.IOException;
 4 import java.net.DatagramPacket;
 5 import java.net.DatagramSocket;
 6 import java.net.SocketException;
 7 import java.awt.BorderLayout;
 8 import javax.swing.JFrame;
 9 import javax.swing.JScrollPane;
10 import javax.swing.JTextArea;
11 import javax.swing.SwingUtilities;
12
13 public class Server extends JFrame
14 {
15 private JTextArea displayArea; // displays packets received
16 private DatagramSocket socket; // socket to connect to client
17
18 // set up GUI and DatagramSocket
19 public Server()
20 {
21 super( "Server" );
22
23 displayArea = new JTextArea(); // create displayArea
24 add( new JScrollPane( displayArea ), BorderLayout.CENTER );
25 setSize( 400, 300 ); // set size of window
26 setVisible( true ); // show window
27
28 try // create DatagramSocket for sending and receiving packets
29 {
30 socket = new DatagramSocket( 5000 );
31 } // end try
32 catch ( SocketException socketException )
33 {
34 socketException.printStackTrace();
35 System.exit( 1 );
36 } // end catch
37 } // end Server constructor
38
39 // wait for packets to arrive, display data and echo packet to client
40 public void waitForPackets()
41 {
42 while ( true )
43 {
44 try // receive packet, display contents, return copy to client
45 {
46 byte data[] = new byte[ 100 ]; // set up packet
47 DatagramPacket receivePacket = 
48  new DatagramPacket( data, data.length ); 
49
50 socket.receive( receivePacket ); // wait to receive packet
51
52 // display information from received packet
53 displayMessage( "
Packet received:" +
54 "
From host: " + receivePacket.getAddress() +
55 "
Host port: " + receivePacket.getPort() +
56 "
Length: " + receivePacket.getLength() +
57 "
Containing:
	" + new String( receivePacket.getData(),
58 0, receivePacket.getLength() ) );
59
60 sendPacketToClient( receivePacket ); // send packet to client
61 } // end try
62 catch ( IOException ioException )
63 {
64 displayMessage( ioException.toString() + "
" );
65 ioException.printStackTrace();
66 } // end catch
67 } // end while
68 } // end method waitForPackets
69
70 // echo packet to client
71 private void sendPacketToClient( DatagramPacket receivePacket )
72 throws IOException
73 {
74 displayMessage( "

Echo data to client..." );
75
76 // create packet to send
77 DatagramPacket sendPacket = new DatagramPacket( 
78  receivePacket.getData(), receivePacket.getLength(), 
79  receivePacket.getAddress(), receivePacket.getPort() );
80
81 socket.send( sendPacket ); // send packet to client
82 displayMessage( "Packet sent
" );
83 } // end method sendPacketToClient
84
85 // manipulates displayArea in the event-dispatch thread
86 private void displayMessage( final String messageToDisplay )
87 {
88 SwingUtilities.invokeLater(
89 new Runnable()
90 {
91 public void run() // updates displayArea
92 {
93 displayArea.append( messageToDisplay ); // display message
94 } // end method run
95 } // end anonymous inner class
96 ); // end call to SwingUtilities.invokeLater
97 } // end method displayMessage
98 } // end class Server

Figure 24.10. Class that tests the Server.

(This item is displayed on pages 1134 - 1135 in the print version)

 1 // Fig. 24.10: ServerTest.java
 2 // Tests the Server class.
 3 import javax.swing.JFrame;
 4
 5 public class ServerTest
 6 {
 7 public static void main( String args[] )
 8 {
 9 Server application = new Server(); // create server
10 application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
11 application.waitForPackets(); // run server application
12 } // end main
13 } // end class ServerTest
 

Server window after packet of data is received from Client

Figure 24.11. Client side of connectionless client/server computing with datagrams.

(This item is displayed on pages 1135 - 1137 in the print version)

 1 // Fig. 24.11: Client.java
 2 // Client that sends and receives packets to/from a server.
 3 import java.io.IOException;
 4 import java.net.DatagramPacket;
 5 import java.net.DatagramSocket;
 6 import java.net.InetAddress;
 7 import java.net.SocketException;
 8 import java.awt.BorderLayout;
 9 import java.awt.event.ActionEvent;
10 import java.awt.event.ActionListener;
11 import javax.swing.JFrame;
12 import javax.swing.JScrollPane;
13 import javax.swing.JTextArea;
14 import javax.swing.JTextField;
15 import javax.swing.SwingUtilities;
16 
17 public class Client extends JFrame
18 {
19 private JTextField enterField; // for entering messages
20 private JTextArea displayArea; // for displaying messages
21 private DatagramSocket socket; // socket to connect to server
22 
23 // set up GUI and DatagramSocket
24 public Client()
25 {
26 super( "Client" );
27 
28 enterField = new JTextField( "Type message here" );
29 enterField.addActionListener(
30 new ActionListener()
31 {
32 public void actionPerformed( ActionEvent event )
33 {
34 try // create and send packet
35 {
36 // get message from textfield
37 String message = event.getActionCommand();
38 displayArea.append( "
Sending packet containing: " +
39 message + "
" );
40 
41 byte data[] = message.getBytes(); // convert to bytes
42 
43 // create sendPacket
44 DatagramPacket sendPacket = new DatagramPacket( data,
45  data.length, InetAddress.getLocalHost(), 5000 ); 
46 
47 socket.send( sendPacket ); // send packet
48 displayArea.append( "Packet sent
" );
49 displayArea.setCaretPosition(
50 displayArea.getText().length() );
51 } // end try
52 catch ( IOException ioException )
53 {
54 displayMessage( ioException.toString() + "
" );
55 ioException.printStackTrace();
56 } // end catch
57 } // end actionPerformed
58 } // end inner class
59 ); // end call to addActionListener
60 
61 add( enterField, BorderLayout.NORTH );
62 
63 displayArea = new JTextArea();
64 add( new JScrollPane( displayArea ), BorderLayout.CENTER );
65 
66 setSize( 400, 300 ); // set window size
67 setVisible( true ); // show window
68 
69 try // create DatagramSocket for sending and receiving packets
70 {
71 socket = new DatagramSocket();
72 } // end try
73 catch ( SocketException socketException )
74 {
75 socketException.printStackTrace();
76 System.exit( 1 );
77 } // end catch
78 } // end Client constructor
79 
80 // wait for packets to arrive from Server, display packet contents
81 public void waitForPackets()
82 {
83 while ( true )
84 {
85 try // receive packet and display contents
86 {
87 byte data[] = new byte[ 100 ]; // set up packet 
88 DatagramPacket receivePacket = new DatagramPacket(
89  data, data.length ); 
90 
91 socket.receive( receivePacket ); // wait for packet
92 
93 // display packet contents
94 displayMessage( "
Packet received:" +
95 "
From host: " + receivePacket.getAddress() +
96 "
Host port: " + receivePacket.getPort() +
97 "
Length: " + receivePacket.getLength() +
98 "
Containing:
	" + new String( receivePacket.getData(),
99 0, receivePacket.getLength() ) );
100 } // end try
101 catch ( IOException exception )
102 {
103 displayMessage( exception.toString() + "
" );
104 exception.printStackTrace();
105 } // end catch
106 } // end while
107 } // end method waitForPackets
108 
109 // manipulates displayArea in the event-dispatch thread
110 private void displayMessage( final String messageToDisplay )
111 {
112 SwingUtilities.invokeLater(
113 new Runnable()
114 {
115 public void run() // updates displayArea
116 {
117 displayArea.append( messageToDisplay );
118 } // end method run
119 } // end inner class
120 ); // end call to SwingUtilities.invokeLater
121 } // end method displayMessage
122 } // end class Client

Figure 24.12. Class that tests the Client.

(This item is displayed on pages 1137 - 1138 in the print version)

 1 // Fig. 24.12: ClientTest.java
 2 // Tests the Client class.
 3 import javax.swing.JFrame;
 4
 5 public class ClientTest
 6 {
 7 public static void main( String args[] )
 8 {
 9 Client application = new Client(); // create client
10 application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
11 application.waitForPackets(); // run client application
12 } // end main
13 } // end class ClientTest
 

Client window after sending packet to Server and receiving packet back from Server

Server Class

Class Server (Fig. 24.9) declares two DatagramPackets that the server uses to send and receive information and one DatagramSocket that sends and receives the packets. The Server constructor (lines 1937) creates the graphical user interface in which the packets of information will be displayed. Line 30 creates the DatagramSocket in a TRy block. Line 30 uses the DatagramSocket constructor that takes an integer port number argument (5000 in this example) to bind the server to a port where it can receive packets from clients. Clients sending packets to this Server specify the same port number in the packets they send. A SocketException is thrown if the DatagramSocket constructor fails to bind the DatagramSocket to the specified port.

Common Programming Error 24.2

Specifying a port that is already in use or specifying an invalid port number when creating a DatagramSocket results in a SocketException.

Server method waitForPackets (lines 4068) uses an infinite loop to wait for packets to arrive at the Server. Lines 4748 create a DatagramPacket in which a received packet of information can be stored. The DatagramPacket constructor for this purpose receives two argumentsa byte array in which the data will be stored and the length of the array. Line 50 uses DatagramSocket method receive to wait for a packet to arrive at the Server. Method receive blocks until a packet arrives, then stores the packet in its DatagramPacket argument. The method throws an IOException if an error occurs while receiving a packet.

When a packet arrives, lines 5358 call method displayMessage (declared at lines 8697) to append the packet's contents to the textarea. DatagramPacket method getAddress (line 54) returns an InetAddress object containing the host name of the computer from which the packet was sent. Method getPort (line 55) returns an integer specifying the port number through which the host computer sent the packet. Method getLength (line 56) returns an integer representing the number of bytes of data sent. Method getData (line 57) returns a byte array containing the data. Lines 5758 initialize a String object using a three-argument constructor that takes a byte array, the offset and the length. This String is then appended to the text to display.

After displaying a packet, line 60 calls method sendPacketToClient (declared at lines 7183) to create a new packet and send it to the client. Lines 7779 create a DatagramPacket and pass four arguments to its constructor. The first argument specifies the byte array to send. The second argument specifies the number of bytes to send. The third argument specifies the client computer's Internet address, to which the packet will be sent. The fourth argument specifies the port where the client is waiting to receive packets. Line 81 sends the packet over the network. Method send of DatagramSocket throws an IOException if an error occurs while sending a packet.

Client Class

Class Client (Fig. 24.11) works similarly to class Server, except that the Client sends packets only when the user types a message in a textfield and presses the Enter key. When this occurs, the program calls method actionPerformed (lines 3257), which converts the string the user entered into a byte array (line 41). Lines 4445 create a DatagramPacket and initialize it with the byte array, the length of the string that was entered by the user, the IP address to which the packet is to be sent (InetAddress.getLocalHost() in this example) and the port number at which the Server is waiting for packets (5000 in this example). Line 47 sends the packet. Note that the client in this example must know that the server is receiving packets at port 5000otherwise, the server will not receive the packets.

Note that the DatagramSocket constructor call (line 71) in this application does not specify any arguments. This no-argument constructor allows the computer to select the next available port number for the DatagramSocket. The client does not need a specific port number, because the server receives the client's port number as part of each DatagramPacket sent by the client. Thus, the server can send packets back to the same computer and port number from which it receives a packet of information.

Client method waitForPackets (lines 81107) uses an infinite loop to wait for packets from the server. Line 91 blocks until a packet arrives. This does not prevent the user from sending a packet, because the GUI events are handled in the event-dispatch thread. It only prevents the while loop from continuing until a packet arrives at the Client. When a packet arrives, line 91 stores it in receivePacket, and lines 9499 call method displayMessage (declared at lines 110121) to display the packet's contents in the textarea.

Introduction to Computers, the Internet and the World Wide Web

Introduction to Java Applications

Introduction to Classes and Objects

Control Statements: Part I

Control Statements: Part 2

Methods: A Deeper Look

Arrays

Classes and Objects: A Deeper Look

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

GUI Components: Part 1

Graphics and Java 2D™

Exception Handling

Files and Streams

Recursion

Searching and Sorting

Data Structures

Generics

Collections

Introduction to Java Applets

Multimedia: Applets and Applications

GUI Components: Part 2

Multithreading

Networking

Accessing Databases with JDBC

Servlets

JavaServer Pages (JSP)

Formatted Output

Strings, Characters and Regular Expressions

Appendix A. Operator Precedence Chart

Appendix B. ASCII Character Set

Appendix C. Keywords and Reserved Words

Appendix D. Primitive Types

Appendix E. (On CD) Number Systems

Appendix F. (On CD) Unicode®

Appendix G. Using the Java API Documentation

Appendix H. (On CD) Creating Documentation with javadoc

Appendix I. (On CD) Bit Manipulation

Appendix J. (On CD) ATM Case Study Code

Appendix K. (On CD) Labeled break and continue Statements

Appendix L. (On CD) UML 2: Additional Diagram Types

Appendix M. (On CD) Design Patterns

Appendix N. Using the Debugger

Inside Back Cover



Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

Similar book on Amazon

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