Principle 15.7.1. DEBUGGING TIP: Reserved Port Numbers.
Port numbers below 1024 are reserved for system use and should not be used by an application program.
ServerSocket
. The first argument to the ServerSocket()
method is the port at which the service will reside. The second argument specifies the number of clients that can be backlogged, waiting on the server, before a client will be refused service. If more than one client at a time should request service, Java would establish and manage a waiting list, turning away clients when the list is full.accept()
method will block until a connection is established. The Java system is responsible for waking the server when a client request is received.Socket socket; // Reference to the socket
ServerSocket port;// The port where the server will listen
try {
port = new ServerSocket(10001, 5); // Create a port
socket = port.accept(); // Wait for client to call
// Communicate with the client
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
close()
. Thus, there are four steps involved on the server side:ServerSocket
and establish a port number.Socket()
constructor by supplying the server’s URL and port number. Once the connection is established, the client can carry out two-way communication with the server. This step is not shown here. Finally, when the client is finished, it can simply close()
the connection. Thus, from the client side, the protocol involves just three steps:Socket connection; // Reference to the socket
try { // Request a connection
connection = new Socket("java.cs.trincoll.edu", 10001);
// Carry on a two-way communication
connection.close(); // Close the socket
} catch (IOException e ) {
e.printStackTrace();
}
writeToSocket()
and readFromSocket()
, that may be called by either.writeToSocket()
method takes two parameters, the Socket
and a String
, which will be sent to the process on the other end of the socket:protected void writeToSocket(Socket sock, String str)
throws IOException {
oStream = sock.getOutputStream();
for (int k = 0; k < str.length(); k++)
oStream.write(str.charAt(k));
}// writeToSocket()
writeToSocket()
is called by the server, then the string will be sent to the client. If it is called by the client, the string will be sent to the server.protected
because we will define it in a superclass so that it can be inherited and used by both the client and server classes. Note also that the method declares that it throws an IOException
. Because there’s no way to fix an IOException
, we’ll just let this exception be handled elsewhere, rather than handling it within the method.OutputStream
and then write to it. For this example, oStream
is an instance variable of the client/server superclass. We use the Socket.getOutputStream()
method to get a reference to the socket’s output stream. Note that we are not creating a new output stream here. We are just getting a reference to an existing stream, which was created when the socket connection was accepted. Note also that we do not close the output stream before exiting the method. This is important. If you close the stream, you will lose the ability to communicate through the socket.OutputStream.write()
method. This method writes a single byte
. Therefore, the input stream on the other side of the socket must read bytes and convert them back into characters.protected String readFromSocket(Socket sock)
throws IOException {
iStream = sock.getInputStream();
String str="";
char c;
while ( ( c = (char) iStream.read() ) != '\n')
str = str + c + "";
return str;
}
Socket.getInputStream()
method to obtain a reference to the socket’s input stream, which has already been created. So here again it is important that you don’t close the stream in this method. A socket’s input and output streams will be closed automatically when the socket connection itself is closed.InputStream.read()
method reads a single byte at a time from the input stream until an end-of-line character is received. For this particular application, the client and server will both read and write one line of characters at a time. Note the use of the cast operator (char)
in the read()
statement. Because byte
s are being read, they must be converted to char
before they can be compared to the end-of-line character or concatenated to the String
. When the read loop encounters an end-of-line character, it terminates and returns the String
that was input.byte
and a char
. One must be converted to the other using an explicit cast operator.