10.1 The ServerSocket Class
The ServerSocket class contains everything needed to write
servers in Java. It has constructors that create new
ServerSocket objects, methods that listen for
connections on a specified port, methods that configure the various
server socket options, and the usual miscellaneous methods such as
toString( ).In Java, the basic life cycle of a
server program is:A new ServerSocket is created on a particular port
using a ServerSocket( ) constructor.The ServerSocket listens for incoming connection
attempts on that port using its accept( ) method.
accept( ) blocks until a client attempts to make a
connection, at which point accept( ) returns a
Socket object connecting the client and the
server.Depending on the type of server, either the
Socket's getInputStream() method, getOutputStream( ) method, or
both are called to get input and output streams that communicate with
the client.The server and the client interact according to an agreed-upon
protocol until it is time to close the connection.The server, the client, or both close the connection.The server returns to step 2 and waits for the next connection.If step 4 is likely to take a long or
indefinite amount of time, traditional Unix servers such as wu-ftpd
create a new process to handle each connection so that multiple
clients can be serviced at the same time. Java programs should spawn
a thread to interact with the client so that the server can be ready
to process the next connection sooner.
A thread places a far smaller load on the
server than a complete child process. In fact, the overhead of
forking too many processes is why the typical Unix FTP server
can't handle more than roughly 400 connections
without slowing to a crawl. On the other hand, if the protocol is
simple and quick and allows the server to close the connection when
it's through, then it will be more efficient for the
server to process the client request immediately without spawning a
thread.
|
a particular port in a first-in, first-out queue. The default length
of the queue is normally 50, although it can vary from operating
system to operating system. Some operating systems (not Solaris) have
a maximum queue length, typically five. On these systems, the queue
length will be the largest possible value less than or equal to 50.
After the queue fills to capacity with unprocessed connections, the
host refuses additional connections on that port until slots in the
queue open up. Many (though not all) clients will try to make a
connection multiple times if their initial attempt is refused. The
operating system manages incoming connections and the queue; your
program does not need to worry about it. Several
ServerSocket constructors allow you to change the
length of the queue if its default length isn't
large enough; however, you won't be able to increase
the queue beyond the maximum size that the operating system supports.
10.1.1 The Constructors
There
are four public ServerSocket constructors:
public ServerSocket(int port) throws BindException, IOExceptionThese constructors let you specify the port, the length of the queue
public ServerSocket(int port, int queueLength)
throws BindException, IOException
public ServerSocket(int port, int queueLength, InetAddress bindAddress)
throws IOException
public ServerSocket( ) throws IOException // Java 1.4
used to hold incoming connection requests, and the local network
interface to bind to. They pretty much all do the same thing, though
some use default values for the queue length and the address to bind
to. Let's explore these in order.
10.1.1.1 public ServerSocket(int port) throws BindException, IOException
This constructor creates a server socket on the port specified by the
argument. If you pass 0 for the port number, the system selects an
available port for you. A port chosen for you by the system is
sometimes called an anonymous
port since you don't know its
number. For servers, anonymous ports aren't very
useful because clients need to know in advance which port to connect
to; however, there are a few situations (which we will discuss later)
in which an anonymous port might be useful.For example, to create a server socket that would be used by an HTTP
server on port 80, you would write:
try {
ServerSocket httpd = new ServerSocket(80);
}
catch (IOException ex) {
System.err.println(ex);
}The constructor throws an IOException(specifically, a BindException) if the socket
cannot be created and bound to the requested port. An
IOException when
creating a ServerSocket almost always means one of
two things. Either another server socket, possibly from a completely
different program, is already using the requested port, or
you're trying to connect to a port from 1 to 1,023
on Unix (including Linux and Mac OS X) without root (superuser)
privileges.You can use this constructor to write a variation on the
PortScanner programs of the previous chapter.
Example 10-1 checks for ports on the local machine by
attempting to create ServerSocket objects on them
and seeing on which ports that fails. If you're
using Unix and are not running as root, this program works only for
ports 1,024 and
above.
Example 10-1. Look for local ports
import java.net.*;Here's the output I got when running
import java.io.*;
public class LocalPortScanner {
public static void main(String[] args) {
for (int port = 1; port <= 65535; port++) {
try {
// the next line will fail and drop into the catch block if
// there is already a server running on the port
ServerSocket server = new ServerSocket(port);
}
catch (IOException ex) {
System.out.println("There is a server on port " + port + ".");
} // end catch
} // end for
}
}
LocalPortScanner on my Windows NT 4.0 workstation:
D:\JAVA\JNP2\examples\11>java LocalPortScanner
There is a server on port 135.
There is a server on port 1025.
There is a server on port 1026.
There is a server on port 1027.
There is a server on port 1028.
10.1.1.2 public ServerSocket(int port, int queueLength) throws IOException, BindException
This
constructor opens a server socket on the specified port with a queue
length of your choosing. If the machine has multiple network
interfaces or IP addresses, then it listens on this port on all those
interfaces and IP addresses. The queueLength
argument sets the length of the queue for incoming connection
requeststhat is, how many incoming connections can be stored
at one time before the host starts refusing connections. Some
operating systems have a maximum queue length, typically five. If you
try to expand the queue past that maximum number, the maximum queue
length is used instead. If you pass 0 for the port number, the system
selects an available port.For example, to create a server socket on port 5,776 that would hold
up to 100 incoming connection requests in the queue, you would write:
try {
ServerSocket httpd = new ServerSocket(5776, 100);
}
catch (IOException ex) {
System.err.println(ex);
}The constructor throws an IOException(specifically, a BindException) if the socket
cannot be created and bound to the requested port. However, no
exception is thrown if the queue length is larger than the host OS
supports. Instead, the queue length is simply set to the maximum size
allowed.
10.1.1.3 public ServerSocket(int port, int queueLength, InetAddress bindAddress) throws BindException, IOException
This constructor binds a
server socket to the specified port with the specified queue length.
It differs from the other two constructors in binding only to the
specified local IP address. This constructor is useful for servers
that run on systems with several IP addresses because it allows you
to choose the address to which you'll listen. That
is, the server socket only listens for incoming connections on the
specified address; it won't listen for connections
that come in through the host's other addresses. The
previous two constructors bind to all local IP addresses by default.For example, login.ibiblio.org is a particular
Linux box in North Carolina. It's connected to the
Internet with the IP address 152.2.210.122. The same box has a second
Ethernet card with the local IP address 192.168.210.122 that is not
visible from the public Internet, only from the local network. If for
some reason I wanted to run a server on this host that only responded
to local connections from within the same network, I could create a
server socket that listens on port 5,776 of 192.168.210.122 but not
on port 5,776 of 152.2.210.122, like so:
try {
ServerSocket httpd = new ServerSocket(5776, 10,
InetAddress.getByName("192.168.210.122"));
}
catch (IOException ex) {
System.err.println(ex);
}The constructor throws an IOException (again,really a BindException) if the socket cannot be
created and bound to the requested port or network interface.
10.1.1.4 public ServerSocket( ) throws IOException // Java 1.4
The public no-args constructor is new
in Java 1.4. It creates a ServerSocket object but
does not actually bind it to a port so it cannot initially accept any
connections. It can be bound later using the bind() methods also introduced in Java 1.4:
public void bind(SocketAddress endpoint) throws IOException // Java 1.4The primary use for this feature is to allow programs to set server
public void bind(SocketAddress endpoint, int queueLength) // Java 1.4
throws IOException
socket options before binding to a port. Some options are fixed after
the server socket has been bound. The general pattern looks like
this:
ServerSocket ss = new ServerSocket( );You can also past null for the SocketAddress to
// set socket options...
SocketAddress http = new InetSocketAddress(80);
ss.bind(http);
select an arbitrary port. This is like passing 0 for the port number
in the other constructors.
10.1.2 Accepting and Closing Connections
A ServerSocket customarily operates in a loop
that repeatedly accepts connections. Each pass through the loop
invokes the accept( ) method. This returns a
Socket object representing the connection between
the remote client and the local server. Interaction with the client
takes place through this Socket object. When the
transaction is finished, the server should invoke the
Socket object's close() method. If the client closes the connection while the
server is still operating, the input and/or output streams that
connect the server to the client throw an
InterruptedIOException on the next read or write.
In either case, the server should then get ready to process the next
incoming
connection. However, when the server needs to shut
down and not process any further incoming connections, you should
invoke the ServerSocket object's
close( ) method.
10.1.2.1 public Socket accept( ) throws IOException
When server setup is done and
you're ready to accept a connection, call the
ServerSocket's accept() method. This method
"blocks"; that is, it stops the
flow of execution and waits until a client connects. When a client
does connect, the accept( ) method returns a
Socket object. You use the streams returned by
this Socket's
getInputStream( ) and getOutputStream(
) methods to communicate with the client. For example:
ServerSocket server = new ServerSocket(5776);If you don't want the program to halt while it waits
while (true) {
Socket connection = server.accept( );
OutputStreamWriter out
= new OutputStreamWriter(connection.getOutputStream( ));
out.write("You've connected to this server. Bye-bye now.\r\n");
connection.close( );
}
for a connection, put the call to accept( ) in a
separate thread.
|
convoluted. It's important to distinguish between
exceptions that should probably shut down the server and log an error
message, and exceptions that should just close that active
connection. Exceptions thrown by accept( ) or the
input and output streams generally should not shut down the server.
Most other exceptions probably should. To do this,
you'll need to nest your try
blocks.Finally, most servers will want to make sure that all sockets they
accept are closed when they're finished. Even if the
protocol specifies that clients are responsible for closing
connections, clients do not always strictly adhere to the protocol.
The call to close( ) also has to be wrapped in a
try block that catches an
IOException. However, if you do catch an
IOException when closing the socket, ignore it. It
just means that the client closed the socket before the server could.
Here's a slightly more realistic example:
try {
ServerSocket server = new ServerSocket(5776);
while (true) {
Socket connection = server.accept( );
try {
Writer out
= new OutputStreamWriter(connection.getOutputStream( ));
out.write("You've connected to this server. Bye-bye now.\r\n");
out.flush( );
connection.close( );
}
catch (IOException ex) {
// This tends to be a transitory error for this one connection;
// e.g. the client broke the connection early. Consequently,
// you don't want to break the loop or print an error message.
// However, you might choose to log this exception in an error log.
}
finally {
// Guarantee that sockets are closed when complete.
try {
if (connection != null) connection.close( );
}
catch (IOException ex) {}
}
}
catch (IOException ex) {
System.err.println(ex);
}Example 10-2 implements a simple daytime server, asper RFC 867. Since this server just sends a single line of text in
response to each connection, it processes each connection
immediately. More complex servers should spawn a thread to handle
each request. In this case, the overhead of spawning a thread would
be greater than the time needed to process the request.
|
Example 10-2. A daytime server
import java.net.*;Example 10-2 is straightforward. The first three
import java.io.*;
import java.util.Date;
public class DaytimeServer {
public final static int DEFAULT_PORT = 13;
public static void main(String[] args) {
int port = DEFAULT_PORT;
if (args.length > 0) {
try {
port = Integer.parseInt(args[0]);
if (port < 0 || port >= 65536) {
System.out.println("Port must between 0 and 65535");
return;
}
}
catch (NumberFormatException ex) {
// use default port
}
}
try {
ServerSocket server = new ServerSocket(port);
Socket connection = null;
while (true) {
try {
connection = server.accept( );
Writer out = new OutputStreamWriter(connection.getOutputStream( ));
Date now = new Date( );
out.write(now.toString( ) +"\r\n");
out.flush( );
connection.close( );
}
catch (IOException ex) {}
finally {
try {
if (connection != null) connection.close( );
}
catch (IOException ex) {}
}
} // end while
} // end try
catch (IOException ex) {
System.err.println(ex);
} // end catch
} // end main
} // end DaytimeServer
lines import the usual packages, java.io and
java.net, as well as
java.util.Date, which provides the time as read by
the server's internal clock. There is a single
public final
static int field (i.e., a
constant) in the class DEFAULT_PORT, which is set
to the well-known port for a daytime server (port 13). The class has
a single method, main( ), which does all the work.
If the port is specified on the command line, then
it's read from args[0].
Otherwise, the default port is used.The outer try block traps any
IOExceptions that may arise while the
ServerSocket object server is
constructed on the daytime port or when it accepts connections. The
inner try block watches for exceptions thrown
while the connections are accepted and processed. The
accept( ) method is called within an infinite loop
to watch for new connections; like many servers, this program never
terminates but continues listening until an exception is thrown or
you stop it manually.
Socket, which is stored in the local variable
connection, and the program continues. It calls
getOutputStream( ) to get the output stream
associated with that Socket and then chains that
output stream to a new OutputStreamWriter,
out. A new Date object provides
the current time. The content is sent to the client by writing its
string representation on out with write().Finally, after the data is sent or an exception has been thrown, the
finally block closes the
connection. Always close a
socket
when you're finished with it. In the previous
chapter, I said that a client shouldn't rely on the
other side of a connection to close the socket: that goes triple for
servers. Clients time out or crash; users cancel transactions;
networks go down in high-traffic periods. For any of these or a dozen
more reasons, you cannot rely on clients to close sockets, even when
the protocol requires them to, which this one
doesn't.Sending binary,
nontext data is not significantly harder. Example 10-3 demonstrates with a time server that follows
the time protocol outlined in
RFC 868. When a client connects, the server sends a 4-byte,
big-endian, unsigned integer specifying the number of seconds that
have passed since 12:00 A.M., January 1, 1900 GMT (the epoch). Once
again, the current time is found by creating a new
Date object. However, since the
Date class counts milliseconds since 12:00 A.M.,
January 1, 1970 GMT rather than seconds since 12:00 A.M., January 1,
1900 GMT, some conversion is necessary.
Example 10-3. A time server
import java.net.*;As with the TimeClient of the previous chapter,
import java.io.*;
import java.util.Date;
public class TimeServer {
public final static int DEFAULT_PORT = 37;
public static void main(String[] args) {
int port = DEFAULT_PORT;
if (args.length > 0) {
try {
port = Integer.parseInt(args[0]);
if (port < 0 || port >= 65536) {
System.out.println("Port must between 0 and 65535");
return;
}
}
catch (NumberFormatException ex) {}
}
// The time protocol sets the epoch at 1900,
// the Date class at 1970. This number
// converts between them.
long differenceBetweenEpochs = 2208988800L;
try {
ServerSocket server = new ServerSocket(port);
while (true) {
Socket connection = null;
try {
connection = server.accept( );
OutputStream out = connection.getOutputStream( );
Date now = new Date( );
long msSince1970 = now.getTime( );
long secondsSince1970 = msSince1970/1000;
long secondsSince1900 = secondsSince1970
+ differenceBetweenEpochs;
byte[] time = new byte[4];
time[0]
= (byte) ((secondsSince1900 & 0x00000000FF000000L) >> 24);
time[1]
= (byte) ((secondsSince1900 & 0x0000000000FF0000L) >> 16);
time[2]
= (byte) ((secondsSince1900 & 0x000000000000FF00L) >> 8);
time[3] = (byte) (secondsSince1900 & 0x00000000000000FFL);
out.write(time);
out.flush( );
} // end try
catch (IOException ex) {
} // end catch
finally {
if (connection != null) connection.close( );
}
} // end while
} // end try
catch (IOException ex) {
System.err.println(ex);
} // end catch
} // end main
} // end TimeServer
most of the effort here goes into working with a data format (32-bit
unsigned integers) that Java doesn't natively
support.
10.1.2.2 public void close( ) throws IOException
If you're finished with
a server socket, you should close it, especially if the program is
going to continue to run for some time. This frees up the port for
other programs that may wish to use it. Closing a
ServerSocket should
not be confused with closing a Socket. Closing a
ServerSocket frees a port on the local host,
allowing another server to bind to the port; it also breaks all
currently open sockets that the ServerSocket has
accepted.Server sockets are closed automatically when a program dies, so
it's not absolutely necessary to close them in
programs that terminate shortly after the
ServerSocket is no longer needed. Nonetheless, it
doesn't hurt. For example, the main loop of the
LocalPortScanner program might be better written
like this so that it doesn't temporarily occupy most
of the ports on the system:
for (int port = 1; port <= 65535; port++) {
try {
// the next line will fail and drop into the catch block if
// there is already a server running on the port
ServerSocket server = new ServerSocket(port);
server.close( );
}
catch (IOException ex) {
System.out.println("There is a server on port " + port + ".");
}
} // end forAfter the server socket has been closed, it cannot be reconnected,even to the same port.Java 1.4 adds an isClosed( ) method that returns
true if the ServerSocket has been closed, false if
it hasn't:
public boolean isClosed( ) // Java 1.4ServerSocket objects that were created with the
no-args ServerSocket( ) constructor and not yet
bound to a port are not considered to be closed. Invoking
isClosed( ) on these objects returns false. Java
1.4 also adds an isBound(
) method that tells you whether the
ServerSocket has been bound to a port:
public boolean isBound( ) // Java 1.4As with the isBound( ) method of the
Socket class discussed in the last chapter, the
name is a little misleading. isBound( ) returns
true if the ServerSocket has ever been bound to a
port, even if it's currently closed. If you need to
test whether a ServerSocket is open, you must
check both that isBound( ) returns true and that
isClosed( ) returns false. For example:
public static boolean isOpen(ServerSocket ss) {
return ss.isBound( ) && ! ss.isClosed( );
}10.1.3 The get Methods
The ServerSocket
class provides two getter methods that tell you the local address and
port occupied by the server socket. These are useful if
you've opened a server socket on an anonymous port
and/or an unspecified network interface. This would be the case, for
one example, in the data connection of an FTP session.
10.1.3.1 public InetAddress getInetAddress( )
This method returns the address being
used by the server (the local host). If the local host has a single
IP address (as most do), this is the address returned by
InetAddress.getLocalHost( ). If the local host has
more than one IP address, the specific address returned is one of the
host's IP addresses. You can't
predict which address you will get. For example:
ServerSocket httpd = new ServerSocket(80);If the ServerSocket has not yet bound to a network
InetAddress ia = httpd.getInetAddress( );
interface, this method returns null.
10.1.3.2 public int getLocalPort( )
The ServerSocket
constructors allow you to listen on an unspecified port by passing 0
for the port number. This method lets you find out what port
you're listening on. You might use this in a
peer-to-peer multisocket program where you already have a means to
inform other peers of your location. Or a server might spawn several
smaller servers to perform particular operations. The well-known
server could inform clients what ports they can find the smaller
servers on. Of course, you can also use getLocalPort() to find a non-anonymous port, but why would you need to?
Example 10-4
demonstrates.
Example 10-4. A random port
import java.net.*;Here's the output of several runs:
import java.io.*;
public class RandomPort {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(0);
System.out.println("This server runs on port "
+ server.getLocalPort( ));
}
catch (IOException ex) {
System.err.println(ex);
}
}
}
D:\JAVA\JNP3\examples\10>java RandomPortAt least on this VM, the ports aren't really random,
This server runs on port 1154
D:\JAVA\JNP3\examples\10>java RandomPort
This server runs on port 1155
D:\JAVA\JNP3\examples\10>java RandomPort
This server runs on port 1156
but they are at least indeterminate until runtime.If the ServerSocket has not yet bound to a port,
then this method returns -1.
10.1.4 Socket Options
Java 1.3 only supports one socket option for server sockets,
SO_TIMEOUT. Java 1.4 adds two more, SO_REUSEADDR and SO_RCVBUF.
10.1.4.1 SO_TIMEOUT
SO_TIMEOUT is the amount of time, in
milliseconds, that accept( ) waits for an incoming
connection before throwing a
java.io.InterruptedIOException. If SO_TIMEOUT is
0, accept( ) will never time out. The default is
to never time out.Using SO_TIMEOUT is rather rare. You might need it if you were
implementing a complicated and secure protocol that required multiple
connections between the client and the server where responses needed
to occur within a fixed amount of time. However, most servers are
designed to run for indefinite periods of time and therefore just use
the default timeout value, 0 (never time out). If you want to change
this, the setSoTimeout( ) method sets the
SO_TIMEOUT field for this server socket object.
public void setSoTimeout(int timeout) throws SocketExceptionThe countdown starts when accept()
public int getSoTimeout( ) throws IOException
is invoked. When the timeout expires, accept( )
throws an InterruptedIOException. (In Java 1.4, it
throws SocketTimeoutException, a subclass of
InterruptedIOException.) You should set this
option before calling accept( ); you cannot change
the timeout value while accept( ) is waiting for a
connection. The timeout argument must be greater
than or equal to zero; if it isn't, the method
throws an IllegalArgumentException. For example:
try {
ServerSocket server = new ServerSocket(2048);
server.setSoTimeout(30000); // block for no more than 30 seconds
try {
Socket s = server.accept( );
// handle the connection
// ...
}
catch (InterruptedIOException ex) {
System.err.println("No connection within 30 seconds");
}
finally {
server.close( );
}
catch (IOException ex) {
System.err.println("Unexpected IOException: " + e);
}The getSoTimeout() method returns thisserver socket's current SO_TIMEOUT value. For
example:
public void printSoTimeout(ServerSocket server) {
int timeout = server.getSoTimeOut( );
if (timeout > 0) {
System.out.println(server + " will time out after "
+ timeout + "milliseconds.");
}
else if (timeout == 0) {
System.out.println(server + " will never time out.");
}
else {
System.out.println("Impossible condition occurred in " + server);
System.out.println("Timeout cannot be less than zero." );
}
}10.1.4.2 SO_REUSEADDR // Java 1.4
The SO_REUSEADDR option for
server sockets is very similar to the same option for client sockets,
discussed in the last chapter. It determines whether a new socket
will be allowed to bind to a previously used port while there might
still be data traversing the network addressed to the old socket. As
you probably expect, there are two methods to get and set this
option:
public void setReuseAddress(boolean on) throws SocketExceptionThe default value is platform-dependent. This code fragment
public boolean getReuseAddress( ) throws SocketException
determines the default value by creating a new
ServerSocket and then calling
getReuseAddress( ):
ServerSocket ss = new ServerSocket(10240);On the Linux and Mac OS X boxes where I tested this code, server
System.out.println("Reusable: " + ss.getReuseAddress( ));
sockets were reusable.
10.1.4.3 SO_RCVBUF // Java 1.4
The SO_RCVBUF option sets the
default receive buffer size for client sockets accepted by the server
socket. It's read and written by these two methods:
public void setReceiveBufferSize(int size) throws SocketExceptionSetting SO_RCVBUF on a server socket is like calling
public int getReceiveBufferSize( ) throws SocketException
setReceiveBufferSize( ) on each individual socket
returned by accept( ) (except that you
can't change the receive buffer size after the
socket has been accepted). Recall from the last chapter that this
option suggests a value for the size of the individual IP packets in
the stream. Faster connections will want to use larger packets,
although most of the time the default value is fine.You can set this option before or after the server socket is bound,
unless you want to set a receive buffer size larger than 64K. In that
case, you must set the option on an unbound
ServerSocket before binding it. For example:
ServerSocket ss = new ServerSocket( );
int receiveBufferSize = ss.getReceiveBufferSize( );
if (receiveBufferSize < 131072) {
ss.setReceiveBufferSize(131072);
}
ss.bind(new InetSocketAddress(8000));
//...
10.1.4.4 public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) // Java 1.5
Java 1.5 adds a slightly different
method for setting socket optionsthe
setPerformancePreferences() method:
public void setPerformancePreferences(int connectionTime, int latency,This method expresses the relative preferences given to connection
int bandwidth)
time, latency, and bandwidth. For instance, if
connectionTime is 2 and latency
is 1 and bandwidth is 3, then maximum bandwidth is
the most important characteristic, minimum latency is the least
important, and connection time is in the middle. Exactly how any
given VM implements this is implementation-dependent. Indeed, it may
be a no-op in some implementations. The API documentation for
ServerSocket even suggests using non-TCP/IP
sockets, although it's not at all clear what that
means.
10.1.5 The Object Methods
ServerSocket
overrides only one of the standard methods from
java.lang.Object, toString( ).
Thus, equality comparisons test for strict identity and server
sockets are problematic in hash tables. Normally, this
isn't a large problem.
10.1.5.1 public String toString( )
A String returned by
ServerSocket's toString(
) method looks like this:
ServerSocket[addr=0.0.0.0,port=0,localport=5776]addr is the address of the local network interface
to which the server socket is bound. This will be 0.0.0.0 if
it's bound to all interfaces, as is commonly the
case. port is always 0. The
localport is the local port on which the server is
listening for connections. This method is sometimes useful for
debugging, but not much more. Don't rely on it.
10.1.6 Implementation
The ServerSocket class provides two methods for
changing the default implementation of server sockets.
I'll describe them only briefly here, since
they're primarily intended for implementers of Java
virtual machines rather than application programmers.
10.1.6.1 public static void setSocketFactory(SocketImplFactory factory) throws IOException
This method sets the system's
server SocketImplFactory,
which is the factory used to create ServerSocket
objects. This is not the same factory that is used to create client
Socket objects, though the syntax is similar; you
can have one factory for Socket objects and a
different factory for ServerSocket objects. You
can set this factory only once in a program, however. A second
attempt to set the SocketImplFactory throws a
SocketException.
10.1.6.2 protected final void implAccept(Socket s) throws IOException
Subclasses of
ServerSocket use this method when they want to
override accept( ) so that it returns an instance
of their own custom Socket subclass rather than a
plain java.net.Socket. The overridden
accept( ) method passes its own unconnected
Socket object to this method to actually make the
connection. You pass an unconnected Socket object
to implAccept( ). When implAccept(
) returns, the Socket argument
s is connected to a client. For example:
public Socket accept( ) throws IOException {
Socket s = new MySocketSubclass( );
implAccept(s);
return s;
}If the server needs to know that the Socketreturned by accept( ) has a more specific type
than just java.net.Socket, it must cast the return
value appropriately. For example:
ServerSocket server = new MyServerSocketSubclass(80);
while (true) {
MySocketSubclass socket = (MySocketSubclass) server.accept( );;
// ...
}
• Table of Contents• Index• Reviews• Reader Reviews• Errata• AcademicJava Network Programming, 3rd EditionBy
Elliotte Rusty Harold Publisher: O'ReillyPub Date: October 2004ISBN: 0-596-00721-3Pages: 706
Thoroughly revised to cover all the 100+ significant updates
to Java Developers Kit (JDK) 1.5, Java Network
Programming is a complete introduction to
developing network programs (both applets and applications)
using Java, covering everything from networking fundamentals
to remote method invocation (RMI). It includes chapters on
TCP and UDP sockets, multicasting protocol and content
handlers, servlets, and the new I/O API. This is the
essential resource for any serious Java developer.
