Recipe 17.1 Opening a Server for Business


Problem

You need to write a socket-based server.

Solution

Create a ServerSocket for the given port number.

Discussion

The ServerSocket represents the "other end" of a connection, the server that waits patiently for clients to come along and connect to it. You construct a ServerSocket with just the port number.[1] Since it doesn't need to connect to another host, it doesn't need a particular host's address as the client socket constructor does.

[1] You may not be able to pick just any port number for your own service, of course. Certain well-known port numbers are reserved for specific services and listed in your services file, such as 22 for Secure Shell, 25 for SMTP, and hundreds more. Also, on server-based operating systems, ports below 1024 are considered "privileged" ports and require root or administrator privilege to create. This was an early security mechanism; today, with zillions of single-user desktops connected to the Internet, it provides little real security, but the restriction remains.

Assuming the ServerSocket constructor doesn't throw an exception, you're in business. Your next step is to await client activity, which you do by calling accept( ) . This call blocks until a client connects to your server; at that point, the accept( ) returns to you a Socket object (not a ServerSocket) that is connected in both directions to the Socket object on the client (or its equivalent, if written in another language). Example 17-1 shows the code for a socket-based server.

Example 17-1. Listen.java
/**  * Listen -- make a ServerSocket and wait for connections.  */ public class Listen {     /** The TCP port for the service. */     public static final short PORT = 9999;     public static void main(String[] argv) throws IOException {         ServerSocket sock;         Socket  clientSock;         try {             sock = new ServerSocket(PORT);             while ((clientSock = sock.accept(  )) != null) {                 // Process it.                 process(clientSock);             }         } catch (IOException e) {             System.err.println(e);         }     }     /** This would do something with one client. */     static void process(Socket s) throws IOException {         System.out.println("Accept from client " + s.getInetAddress(  ));         // The conversation would be here.         s.close(  );     } }

You would normally use the socket for reading and writing, as shown in the next few recipes.

You may want to listen only on a particular network interface . While we tend to think of network addresses as computer addresses, the two are not the same. A network address is actually the address of a particular network card, or network interface connection, on a given computing device. A desktop computer, laptop, Palm handheld, or cellular phone might have only a single interface, hence a single network address. But a large server machine might have two or more interfaces, usually when it is connected to several networks. A network router is a box (either special-purpose, e.g., a Cisco router, or general-purpose, e.g., a Unix host) that has interfaces on multiple networks and has both the capability and the administrative permission to forward packets from one network to another. A program running on such a server machine might want to provide services only to its inside network or its outside network. One way to accomplish this is by specifying the network interface to be listened on. Suppose you want to provide a different view of web pages for your intranet than you provide to outside customers. For security reasons, you probably wouldn't run both these services on the same machine. But if you wanted to, you could do this by providing the network interface addresses as arguments to the ServerSocket constructor.

However, to use this form of the constructor, you don't have the option of using a string for the network address's name, as you did with the client socket; you must convert it to an InetAddress object. You also have to provide a backlog argument, which is the number of connections that can queue up to be accepted before clients are told that your server is too busy. The complete setup is shown in Example 17-2.

Example 17-2. ListenInside.java
/**  * ListenInside -- make a server socket that listens only on  * a particular interface, in this case, one named by INSIDE_HOST.  */ public class ListenInside {     /** The TCP port for the service. */     public static final short PORT = 9999;     /** The name of the network interface. */     public static final String INSIDE_HOST = "acmewidgets-inside";     /** The number of clients allowed to queue */     public static final int BACKLOG = 10;     public static void main(String[] argv) throws IOException {         ServerSocket sock;         Socket  clientSock;         try {             sock = new ServerSocket(PORT, BACKLOG,                  InetAddress.getByName(INSIDE_HOST));             while ((clientSock = sock.accept(  )) != null) {                 // Process it.                 process(clientSock);             }         } catch (IOException e) {             System.err.println(e);         }     }     /** Hold server's conversation with one client. . */     static void process(Socket s) throws IOException {         System.out.println("Connected from  " + INSIDE_HOST + "": " + s.getInetAddress(  ));         // The conversation would be here.         s.close(  );     } }

The InetAddress.getByName( ) looks up the given hostname in a system-dependent way, referring to a configuration file in the /etc or \windows directory, or to some kind of resolver such as the Domain Name System. Consult a good book on networking and system administration if you need to modify this data.



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

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