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;[37] 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 16-1 shows the code for a
socket-based server.
Example 16-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., Cisco, 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 wanted to provide a different view of web
pages for your intranet than you provided 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 16-2.
Example 16-2. ListenInside.java
/** * ListenInside -- make a server socket that listens only on * a particular interface, in this case, one called "inside". */ 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); } } /** This would do something with one client. */ static void process(Socket s) throws IOException { System.out.println("Accept from inside " + 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 Service. Consult
a good book on networking and system administration if you need to
modify this data.
[37] You can’t just pick any port number for your own service,
of course. There are certain well-known ports 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
form of security mechanism; today, with zillions of single-user
desktops connected to the Internet, it provides little, but the
restriction remains.
3.135.198.174