29.6. JOptionPane Dialogs

 
[Page 850 ( continued )]

25.10. (Optional) Datagram Socket

Clients and servers that communicate via a stream socket have a dedicated point-to-point channel between them. To communicate, they establish a connection, transmit the data, and then close the connection. The stream sockets use TCP (Transmission Control Protocol) for data transmission. Since TCP can detect lost transmissions and resubmit them, transmissions are lossless and reliable. All data sent via a stream socket is received in the same order in which it was sent.

In contrast, clients and servers that communicate via a datagram socket do not have a dedicated point-to-point channel. Data is transmitted using packets. Datagram sockets use UDP ( User Datagram Protocol), which cannot guarantee that the packets are not lost, or not received in duplicate, or received in the order in which they were sent. A datagram is an independent, self-contained message sent over the network whose arrival, arrival time, and content are not guaranteed .

In an analogy, a stream socket communication between a client and a server is like a telephone connection with a dedicated link. A datagram communication is like sending a letter through the post office. Your letter is contained in an envelope ( packet ). If the letter is too large, it may be sent in several envelopes (packets). There is no guarantee that your letter will arrive or that the envelopes will arrive in the order they were sent. One difference is that the letter will not arrive in duplicate, whereas a datagram packet may arrive in duplicate.

Most applications require reliable transmission between clients and servers. In such cases, it is best to use stream socket network communication. Some applications that you write to communicate over the network will not require the reliable, point-to-point channel provided by TCP. In such cases, datagram communication is more efficient.

25.10.1. The DatagramPacket and DatagramSocket Classes

The java.net package contains two classes to help you write Java programs that use datagrams to send and receive packets over the network: DatagramPacket and DatagramSocket . An application can send and receive DatagramPackets through a DatagramSocket .

The DatagramPacket Class

The DatagramPacket class represents a datagram packet. Datagram packets are used to implement a connectionless packet-delivery service. Each message is routed from one machine to another based solely on information contained within the packet.

To create a DatagramPacket for delivery from a client, use the DatagramPacket(byte[] buf, int length, InetAddress host, int port) constructor. To create all other DatagramPackets , use the DatagramPacket(byte[] buf, int length) constructor, as shown in Figure 25.20. Once a datagram packet is created, you can use the getData and setData methods to obtain and set data in the packet.


[Page 851]
Figure 25.20. The DatagramPacket class contains the data and information about data.

DatagramSocket

The DatagramSocket class represents a socket for sending and receiving datagram packets. A datagram socket is the sending or receiving point for a packet-delivery service. Each packet sent or received on a datagram socket is individually addressed and routed. Multiple packets sent from one machine to another may be routed differently, and may arrive in any order.

To create a server DatagramSocket , use the constructor DatagramSocket(int port) , which binds the socket with the specified port on the local host machine.

To create a client DatagramSocket , use the constructor DatagramSocket() , which binds the socket with any available port on the local host machine.

To send data, you need to create a packet, fill in the contents, specify the Internet address and port number for the receiver, and invoke the send(packet) method on a DatagramSocket .

To receive data, you have to create an empty packet and invoke the receive(packet) method on a DatagramSocket .

25.10.2. Datagram Programming

Datagram programming is different from stream socket programming in the sense that there is no concept of a ServerSocket for datagrams. Both client and server use DatagramSocket to send and receive packets, as shown in Figure 25.21.

Figure 25.21. The programs send and receive packets via datagram sockets.
(This item is displayed on page 852 in the print version)

Normally, you designate one application as the server and create a DatagramSocket with the specified port using the constructor DatagramSocket(port) . A client can create a DatagramSocket without specifying a port number. The port number will be dynamically chosen at runtime. When a client sends a packet to the server, the client's IP address and port number are contained in the packet. The server can retrieve it from the packet and use it to send the packet back to the client.

To demonstrate , let us rewrite the client and server programs in Listings 25.1 and 25.2 using datagrams rather than socket streams. The client sends the radius to a server. The server receives this information, uses it to find the area, and then sends the area to the client.

Listing 25.15 gives the server, and Listing 25.16 gives the client. A sample run of the program is shown in Figure 25.22.


[Page 852]
Figure 25.22. The server receives a radius from a client, computes the area, and sends the area to the client. The server can serve multiple clients.

Listing 25.15. DatagramServer.java
(This item is displayed on pages 852 - 853 in the print version)
 1   import   java.io.*; 2   import   java.net.*; 3   import   java.util.*; 4   import   java.awt.*; 5   import   javax.swing.*; 6 7    public class   DatagramServer   extends   JFrame  { 8  // Text area for displaying contents  9   private   JTextArea jta =   new   JTextArea(); 10 11  // The byte array for sending and receiving datagram packets  12   private byte   [] buf =   new byte   [   256   ]; 13 

[Page 853]
 14   public static void   main(String[] args) { 15   new   DatagramServer(); 16 } 17 18   public   Server() { 19  // Place text area on the frame  20 setLayout(   new   BorderLayout()); 21 add(   new   JScrollPane(jta), BorderLayout.CENTER); 22 23 setTitle(   "DatagramServer"   ); 24 setSize(   500   ,   300   ); 25 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 26 setVisible(   true   );  // It is necessary to show the frame here!  27 28   try   { 29  // Create a server socket  30  DatagramSocket socket =   new   DatagramSocket(   8000   );  31 jta.append(   "Server started at "   +   new   Date() +   '\n'   ); 32 33  // Create a packet for receiving data  34  DatagramPacket receivePacket =  35    new   DatagramPacket(buf, buf.length);  36 37  // Create a packet for sending data  38  DatagramPacket sendPacket =  39    new   DatagramPacket(buf, buf.length);  40 41   while   (   true   ) { 42  // Initialize buffer for each iteration  43 Arrays.fill(buf, (   byte   )     ); 44 45  // Receive radius from the client in a packet  46  socket.receive(receivePacket);  47 jta.append(   "The client host name is "   + 48 receivePacket.getAddress().getHostName() + 49   " and port number is "   + receivePacket.getPort() +   '\n'   ); 50 jta.append(   "Radius received from client is "   + 51   new   String(buf).trim() +   '\n'   ); 52 53  // Compute area  54   double   radius = Double.parseDouble(   new   String(buf).trim()); 55   double   area = radius * radius * Math.PI; 56 jta.append(   "Area is "   + area +   '\n'   ); 57 58  // Send area to the client in a packet  59  sendPacket.setAddress(receivePacket.getAddress());  60  sendPacket.setPort(receivePacket.getPort());  61  sendPacket.setData(   new   Double(area).toString().getBytes());  62  socket.send(sendPacket);  63 } 64 } 65   catch   (IOException ex) { 66 ex.printStackTrace(); 67 } 68 } 69 } 


[Page 854]
Listing 25.16. DatagramClient.java
(This item is displayed on pages 854 - 855 in the print version)
 1   import   java.io.*; 2   import   java.net.*; 3   import   java.util.*; 4   import   java.awt.*; 5   import   java.awt.event.*; 6   import   javax.swing.*; 7 8   public class   DatagramClient   extends   JFrame { 9  // Text field for receiving radius  10   private   JTextField jtf =   new   JTextField(); 11 12  // Text area to display contents  13   private   JTextArea jta =   new   JTextArea(); 14 15  // Datagram socket  16   private   DatagramSocket socket; 17 18  // The byte array for sending and receiving datagram packets  19   private byte   [] buf =   new byte   [   256   ]; 20 21  // Server InetAddress  22   private   InetAddress address; 23 24  // The packet sent to the server  25   private   DatagramPacket sendPacket; 26 27  // The packet received from the server  28   private   DatagramPacket receivePacket; 29 30   public static void   main(String[] args) { 31   new   DatagramClient(); 32 } 33 34   public   DatagramClient() { 35  // Panel p to hold the label and text field  36 JPanel p =   new   JPanel(); 37 p.setLayout(   new   BorderLayout()); 38 p.add(   new   JLabel(   "Enter radius"   ), BorderLayout.WEST); 39 p.add(jtf, BorderLayout.CENTER); 40 jtf.setHorizontalAlignment(JTextField.RIGHT); 41 42 setLayout(   new   BorderLayout()); 43 add(p, BorderLayout.NORTH); 44 add(   new   JScrollPane(jta), BorderLayout.CENTER); 45 46  jtf.addActionListener(   new   ButtonListener());  // Register listener   47 48 setTitle(   "DatagramClient"   ); 49 setSize(   500   ,   300   ); 50 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 51 setVisible(   true   );  // It is necessary to show the frame here!  52 53   try   { 54  // get a datagram socket  55  socket =   new   DatagramSocket();  56  address = InetAddress.getByName(   "localhost"   );  57  sendPacket =  58    new   DatagramPacket(buf, buf.length, address,   8000   );  

[Page 855]
 59  receivePacket =   new   DatagramPacket(buf, buf.length);  60 } 61   catch   (IOException ex) { 62 ex.printStackTrace(); 63 } 64 } 65 66   private class   ButtonListener   implements   ActionListener { 67   public void   actionPerformed(ActionEvent e) { 68   try   { 69  // Initialize buffer for each iteration  70 Arrays.fill(buf, (   byte   )     ); 71 72  // Send radius to the server in a packet  73  sendPacket.setData(jtf.getText().trim().getBytes());  74  socket.send(sendPacket);  75 76  // Receive area from the server in a packet  77  socket.receive(receivePacket);  78 79  // Display to the text area  80 jta.append(   "Radius is "   + jtf.getText().trim() +   "\n"   ); 81 jta.append(   "Area received from the server is "   82 + Double.parseDouble(   new   String(buf).trim()) +   '\n'   ); 83 } 84   catch   (IOException ex) { 85 ex.printStackTrace(); 86 } 87 } 88 } 89 } 

Since datagrams are connectionless, a DatagramPacket can be sent to multiple clients, and multiple clients can receive a packet from the same server. As shown in this example, you can launch multiple clients. Each client sends the radius to the server, and the server sends the area back to the client.

The server creates a DatagramSocket on port 8000 (line 30 in DatagramServer.java). No DatagramSocket can be created again on the same port. The client creates a DatagramSocket on an available port (line 55 in DatagramClient.java). The port number is dynamically assigned to the socket. You can launch multiple clients simultaneously , and each client's datagram socket will be different.

The client creates a DatagramPacket named sendPacket for delivery to the server (lines 57 “58 in DatagramClient.java). The DatagramPacket contains the server address and port number. The client creates another DatagramPacket named receivePacket (line 59), which is used for receiving packets from the server. This packet does not need to contain any address or port number.

A user enters a radius in the text field in the client. When the user presses the Enter key on the text field, the radius value in the text field is put into the packet and sent to the server (lines 73 “74 in DatagramClient.java). The server receives the packet (line 46 in DatagramServer.java), extracts the data from the byte array buf , and computes the area (lines 54 “55 in DatagramServer.java). The server then builds a packet that contains the area value in the buffer, the client's address, and the port number, and sends the packet to the client (lines 59 “62). The client receives the packet (line 77 in DatagramClient.java) and displays the result in the text area.

The data in the packet is stored in a byte array. To send a numerical value, you need to convert it into a string and then store it in the array as bytes, using the getBytes() method in the String class (line 62 in DatagramServer.java and line 74 in DatagramClient.java). To convert the array into a number, first convert it into a string, and then convert it into a number using the static parseDouble method in the Double class (line 54 in DatagramServer.java and line 82 in DatagramClient.java).


[Page 856]

Note

The port numbers for the stream socket and the datagram socket are not related . You can use the same port number for a stream socket and a datagram socket simultaneously.


 


Introduction to Java Programming-Comprehensive Version
Introduction to Java Programming-Comprehensive Version (6th Edition)
ISBN: B000ONFLUM
EAN: N/A
Year: 2004
Pages: 503

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