q CSCI.4220 Network Programming Class 9

CSCI.4220 Network Programming
Class 9, Friday, Sept 30, 2006
Java Sockets

If you have not done any java programming before, you should take this brief tutorial before going any further.

Server.java

Our first java program will be a simple server which creates a stream socket in the Internet domain.

There is a class ServerSocket This has four constructors

ServerSocket()
ServerSocket(int port)
ServerSocket(int port, int backlog)
ServerSocket(int port,InetAddress bindaddress)

We will use choice 2. This creates a stream socket, binds it to the local address, and listens. Note that if you want a socket in a different domain or if you want to use a different type of socket such as datagram socket, you need to use a different class. However, this can be used with either IPv4 or IPv6 addresses.

When you look at the documentation for the constructor, you see this.

public ServerSocket() throws IOException

Read the tutorial about exceptions if you do not throroughly understand them.

The ServerSocket class has lots of methods, most of which do not concern us now. Here is one that we need.

Socket accept()

Note that this returns an instance of a Socket which is different from a ServerSocket Recall in class 2, I made a distinction between a listening socket, that listens on a port waiting for a connection, and a reading and writing socket, which is a socket returned from the accept call when a connection has been made. A ServerSocket is the former, a Socket is the latter. The methods are quite different.

Here is the online help for Socket

The two methods that we will need for a Socket are getInputStream() and getOutputStream()

An InputStream is an abstract class, which means that it is not instantiated directly; rather it is used as a base class to derive other classes. Likewise with OutputStream

These are the subclasses (derived classes).

AudioInputStream, 
ByteArrayInputStream, 
FileInputStream, (reads from a file)
FilterInputStream, (abstract superclass)
InputStream, 
ObjectInputStream,(reads serialized data) 
PipedInputStream, 
SequenceInputStream, 
StringBufferInputStream

Here is the method that we can use to read bytes.

public int read(byte[] b)
         throws IOException

Output Stream is also an abstract superclass, so we need to choose a subclass

ByteArrayOutputStream
FileOutputStream
FilterOutputStream
ObjectOutputStream
OutputStream
PipedOutputStream
A FilteredOutputStream is an abstract superclass for
BufferedOutputStream
CheckedOutputStream
CipherOutputStream
DataOutputStream
DeflaterOutputStream
DigestOutputStream
PrintStream
We need to get an input and an output stream for the new socket.

Pay particular attention to the Socket member function getInputStream(). This returns an instance of the class InputStream.. This is an abstract superclass which means that it cannot be instantiated, it can only be used as a base class to derive other classes.

There are two ways to store data, in text or binary, so java has two types, char and byte. Input and output streams are bytes.

To read or write characters, you need the classes Reader and Writer.

There is a class InputStreamReader which converts an input stream (bytes) to a reader (chars)

A charset is named mapping between sequences of sixteen-bit Unicode code units and sequences of bytes. This class defines methods for creating decoders and encoders and for retrieving the various names associated with a charset. Here are a few.

US-ASCII  Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the Unicode character set
ISO-8859-1   ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
UTF-8 Eight-bit UCS Transformation Format
UTF-16BE Sixteen-bit UCS Transformation Format, big-endian byte order
UTF-16LE Sixteen-bit UCS Transformation Format, little-endian byte order
UTF-16 Sixteen-bit UCS Transformation Format, byte order identified by an optional byte-order mark
If you don't specify the charset when you create a reader, it uses the default, which on our systems is US-ASCII. Here is some code.
try {
  Socket s = new Socket(``www.cs.rpi.edu'', 80);
  InputStream in = s.getInputStream();
  InputStreamReader isr = new InputStreamReader(in);
  BufferedReader br = new BufferedReader(isr);
  int c;
  while ((c = br.read()) != -1) {
    System.out.print((char) c);
  }
  System.out.println();
}
catch (IOException ex) {
   System.err.println("Error reading from socket");  
}

Here is the code for server.java

Writing our basic client in java is pretty easy. Note that one of the eight constructors for a Socket is
Socket(String host, int port)
This constructor creates a socket and connects it to the specified port number on the named host. If we use this, the rest of the code for our client is trivial

Here is the code for a client

To compile and run the server on your laptop, open a command prompt window, cd to the directory where the source code is, and type
javac server.java

javac is the java compiler. If you get compiler errors, fix them and try again (my code should not have compiler errors). Once you have a clean compile, there will be a file called server.class in your directory. To run this, type this command
java server 44444
(The last arg is the port.) Like a good server, nothing happens until a client connects.

A threaded server

To implement threads: Here is the code for a threaded server

The URL class

The Class URL represents a Uniform Resource Locator, a pointer to a "resource" on the World Wide Web.

In general, a URL can be broken into several parts. Here is a typical url.

http://java.sun.com:80/index.html#chapter1

This has five fields

The URL class has members to pull all of these fields out.

There is also a member InputStream openStream() which actually opens a connection to this url.

Here is a sample program which demonstrates this. Note that it downloads the course web page without the programmer having to create a socket.

Datagram Sockets

There is a class DatagramSocket
This class has five constructors, one of which takes a single argument, the port to listen on. Our program will use this one. Two other methods that we will use are receive and send. Note that these send and receive DatagramPackets

Here is code for a datagram socket server

Setting and Getting Socket Options

Getting and setting socket options is much easier in java than it is in C (which used the klugy getsockopt function) because there are simple member functions for the class. For example, to get the size of the TCP send buffer for a socket, just use the member function
int getSendBufferSize()
The Socket class has a member function
void setSoTimeout(int timeout)
which allows you to set a timer on a read, and if no data have arrived after the time, it returns. The time unit for the arugment is milliseconds.

Required Reading

There are a bazillion java socket tutorials on the Internet. If you don't believe me, try googling java sockets. But mine is better than any of these. If you are somewhat perplexed you can look at some sample programs which do things a little differently than I do by clicking here

This is not required reading, but Sun has a full on-line Java tutorial at http://java.sun.com/docs/books/tutorial/index.html. The networking trail of the tutorial is at http://java.sun.com/docs/books/tutorial/networking/index.html