Chapter 2: Java Sockets
Chapter 2: Java Sockets
Chapter 2: Java Sockets
import java.net.*;
import java.io.*;
Socket s = new Socket("this.doesnt.exist.com", 1024);
BufferedReader in = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintStream out =
new PrintStream(s.getOutputStream());
(Lines of codes between the import statement and the Socket declaration have been omitted.) The key bits
are (a) s = new Socket(...), which creates a new socket s; (b) s.getInputStream(), which returns
the input stream associated with the socket s; and (c) s.getOutputStream() which returns the
corresponding output stream. The other stuff (BufferedReader, InputStreamReader,
PrintStream) are exactly the same methods we would use if we wished to do line-based IO from files: they
`wrap' the raw input stream with something more convenient and useable. So we can make socket-based
communication look more-or-less exactly like file-based communication.
We can now (say) input (inString = in.readLine();) and output (out.println("blah");) lines
of text in the normal way. (It has to be said though, that Java's stream-based IO, though very flexible and
capable, is not the easiest thing to come to grips with initially.)
connection attempt will typically fail. (We must be a little careful when trying to open sockets because if there is
nobody listening, an exception can be thrown. We are generally required to catch and deal with such exceptions -
not catching most exceptions causes compilation errors). We will look at exceptions some more in the example.)
The class that deals with server sockets is (no suprise) ServerSocket and you can find API details here. The
principal constructor from our point of view is
ServerSocket(int port)
which creates a server socket that listens on the specified port. To set up a server socket and establish a
connection, we might use code like this:
import java.net.*;
SeverSocket sSoc = new ServerSocket(1024);
Socket in = sSoc.accept();
We create a new server socket called sSoc and then call its accept() method. At this point, our code will
wait until some other process (probably on another machine, though this does not have to be the case) connects
to the server socket, by automatically creating a new client socket. The accept method blocks - that is, any
program invoking it will wait until a communication attempt occurs (there are other versions of accept that
specify a maximum waiting time). Once again, we should not use socket numbers less than 1024 because they
are reserved for well-known services.
2.2.1. Simple Example
Here is an example program that repeatedly waits until it is contacted on its server socket. When it is, it starts up
a new thread that outputs the first 100 Fibonacci Numbers (if you don't know what a Fibonacci number is, it
doesn't particularly matter).
import java.net.*;
import java.io.*;
import java.lang.*;
public class Fib1 {
public static void main(String argv[]) {
try {
ServerSocket sSoc = new ServerSocket(2001);
while(true) {
Socket inSoc = sSoc.accept();
FibThread FibT = new FibThread(inSoc);
FibT.start();}
}
catch (Exception e) {
System.out.println("Oh Dear! " +
e.toString());
}
}
}
class FibThread extends Thread {
Socket threadSoc;
int F1 = 1;
int F2 = 1;
FibThread(Socket inSoc) {
threadSoc = inSoc;
}
public void run() {
try {
page 3
import java.net.*;
import java.io.*;
public class FibReader {
Socket appSoc;
BufferedReader in;
String message;
public static void main(String argv[]) {
try {
appSoc = new Socket("wherever",2001);
in = new BufferedReader(new
InputStreamReader(appSoc.getInputStream()));
for (int i = 0; i < 100; i++) {
message = in.readLine();
System.out.println(message); }
}
catch (Exception e) {
System.out.println("Died... " +
e.toString());
}
}
This code creates a socket connection to some host (on which an appropriate server must be running), and sets
up an input stream connected to that socket. It then prints out 100 lines read from the server, using the socket.
Again, this is not particularly good code - for example, we are relying on the server to send us 100 lines: what if
it doesn't? However, it does illustrate the point.
2.4. Exercise
Here is a simple exercise you can try to illustrate that socket communication can work. The java source code file
for the server is here. Download it to your machine. Then download the client. You will probably have to edit
the hostname in the client code - try localhost to start with. Start up the server in a terminal, or command,
window. You might want to do this as a background task - on windows type:
start java Fib1
and on linux:
java Fib1 &
Then type:
java FibReader
and you should see Fibonacci numbers appearing (they will start to go horribly wrong eventually because of
arithmetic overflow).
For experiment two, try doing the same as above, but this time open an extra terminal/command window and
start the client up in both - you should see the Fibonacci numbers appearing more-or-less simultaneously on
both.
The next experiment to try is to use two machines. Start the server up on one, and the client on the other -
remember to edit the hostname in the client (or change the code so it takes command line parameters allowing
you to specify a host. How exactly you manage to use two machines will depend on your circumstances - if you
have access to the Linux laboratory, it is very straightforward. It might also be easy if you have access to
multiple machines at home (though beware that a firewall will almost certainly stop it working - in this case you
can either disable the firewall or open up the port you are using - the safest option).
If you have internet access from outside the university, try the experiment again. ( However, you will need to
start up the server process remotely, e.g. via TelNet, or better ssh - don't start it up in the lab and then go home!
page 5
This may seem obvious but it's been done.) You may find that it doesn't work this time. (I would like to say that
this is a consistent security policy by the University to protect machines from suspicious communication
attempts - but it appears to be purely random.)