ProblemYou need to write a socket-based server. SolutionCreate a ServerSocket for the given port number. DiscussionThe 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.
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. |