Sending objects using socketsTopTalking to a Web server

Talking to a Web server

Now, let's consider how to make an HTTP connection in Java. (Because of Java's URL class, we don't actually need to do this, but it helps understand how the network connection is created and used.)

We need to first create a connection. To do this we create a Socket passing in the name of the machine and the port number. For example, to connect to our Web server we would say:

Socket tcpSocket = new Socket("portal.dci.pomona.edu", 80);

A socket is a lot like a phone connection. When a phone connection is established, you can actually think of this as two connections bundled together. One of these connections alllows you to speak and to your mouthpiece and be heard via the earpiece on the other end. The other connection allows the other person to speak into a mouthpiece and for you to hear what they are saying in your earpiece.

A socket is similarly composed of two streams. The client writes on one stream which the server reads from. This stream is used to send commands from the client to the server. The server writes on another stream which the client reads from. The server uses this stream to send the results of commands to the client.

The next step in writing a client in Java is to get the stream to write to and the stream to read from and create a writer and a reader for them. Notice that we need to make slightly different calls to create the reader and writer, but once created we can use them in the same way as earlier streams:

// Get the stream reader and writer to enable communication
input = new BufferedReader(
	   new InputStreamReader(tcpSocket.getInputStream()));
output = new PrintWriter(tcpSocket.getOutputStream(), true);

Note that a PrintWriter is similar to a FileWriter, except that FileWriter can only write Strings or arrays of characters. PrintWriter can output all types, just as System.out.println.

Now that the connection is established, we can request a Web page by writing the GET command on the output stream. So, to get a Web page, we send the GET command to the server:

output.println("GET " + pageName);

To get to my home page, we would set pageName to "/~kim/".

Now, we need to read the Web page that the server returns over the network connection. This a loop with a style familiar to what we have seen before:

String response = "";
String curline = input.readLine();
while (curline != null) {
   response = response + "\ n" + curline;
   curline = input.readLine();
} 
		
return response;

HTMLLinkFinderUsingSockets is the complete code to manage an HTTP connection.

Notice that the methods in class HTTPConnection have throws clauses as part of their headers. This is because the code in the method bodies throws exceptions that are not handled in the methods. They aren't handled there because they are designed simply to do the I/O. Presumably the application knows better what to do with them. By including the throws clause in the header, we are passing responsibility for handling the exceptions to any method that calls them. (Of course, getWebPage in HTMLLinkFinder also has a throws clause, but the exceptions are finally handled in the actionPerformed method.)

Talking to other types of servers is done in a similar fashion. In all cases, we create a socket and then extract the input and output streams so that we can send commands and read replies. What differs is the protocol, that is, the list of commands that the server will understand. For each command, we need to decide how to process it.

The default port for a POP server is 110.

Here are the commands provided by a POP server:

USER username

This command tells the POP server which user's mail to read. Instead of username you would identify the account to log into. This command responds with a single line which starts with the string +OK.

PASS password

This command tells the POP server the password corresponding to the previous user account. Instead of password you would provide the user's actual password. This command responds with a single line. If the line begins with +OK the login worked. If the login failed, it returns a line beginning with -ERR.

The remaining commands will only work after a successful login.

STAT

This returns some simple statistics about the mailbox. The line it returns has the following form:

+OK 3 496

The first number reports the number of messages in the mailbox. The second reports the total number of characters in all the messages.

TOP 1 0

This returns the header of the message followed by some number of lines. The first number identifies the message number to return. The second number indicates how many lines of the message body to return. As shown above, the command would return only the header for the 1st message.

This message returns first with a line that begins either with +OK or -ERR. It the line it returns begins with +OK, it then sends multiple lines that are the header and the number of body lines requested. You can tell when there it is done sending lines because the last line will consist of a single period character (.).

RETR 1

This command is a lot like TOP except that it returns the entire message requested, both header and body, in their entirety. The number you provide is the message number.

This command returns first with a line that begins either with +OK or -ERR. It the line it returns begins with +OK, it then sends multiple lines that are the header and complete body of the mail message requested. You can tell when there it is done sending lines because the last line will consist of a single period character (.).

QUIT

This command ends the connection with the mail server. It always returns with a single line beginning with +OK.

You can try out this commands using telnet to connect to a mail server on port 110. Just type in the commands shown above and see the responses that you get back.


Sending objects using socketsTopTalking to a Web server