Basic Network Programming in Java

Java has some classes that allows for easy network programming through the use of something called a socket interface. There are two variations of the classes that handle sockets. There is Socket and ServerSocket. Socket sends information out trying to establish a connection to a server. ServerSocket listens waiting for a connection. It’s basically a type of input output stream. Pretty simple in concept. You direct standard input and output through the Socket and information is exchanged between the computers. Java does the rest. In network programming those programs which try to connect to servers to get information are called clients and the computer dishing out information is the server. Servers can server lots of different kinds of information. Each way of doing that is called a service. For example a server can serve email to a client, or a webpage. Clients like internet browsers connect to webservers to get webpages transferring the information stored on the server to the local computer and display it in a sensible way. The manner is which communications between two networked computers exchange information is called a protocol. For webpages the standard protocol is called HTTP or hyper-text transfer protocol. Email is through SMTP – Simple Mail Transfer Protocol. In that case a browser or email reading like Outlook or Thunderbird would be the client program.

To make internet addresses easier to remember a protocol called DNS – domain name service is used. Your computer connects to a DNS server to get the correct address for any website you are looking for and uses that address to direct information to the correct server in a similar way to how you may look in a phone book to get the phone number or street address for a business before you call or drive there. The actual address of a server is called the IP (internet protocol) address. When connecting to the server a webbrowser being a web page client knows it is looking for a particular service so it connects to a particular service being offered by the server. That service is offered on something called a port. A port is like a doorway into the server. The server can have multiple ports. The port that most webservers use to share webpages is port 80. For email it is often 25. But they can be set to any arbitrary port number so you have to make sure your email reader (the client program) is set up correctly to retrieve emails from a particular server and if you are running a webserver it is important to make sure your webserver is serving webpages through port 80 or a person’s browser used to access it will have to be specially directed to use another port.

(An example of directing access to a particular port would be putting in your browser address bar http://www.google.com:80 which would do the same thing as accessing normally since the standard port is port 80.)

IP addresses are rather long which is why DNS is useful. Standards are changing to allow for more server addresses, but the basic IP address format is a set of four up-to-three digit numbers separated by periods. Like 127.0.0.1. That’s the address of your own computer used for testing programs and so forth. It’s called “localhost” automatically so you don’t need a DNS server to tell your computer that. The name of a webaddress is called the hostname and so localhost is your local computer. That makes sense right? Other hostnames include google.com, amazon.com, etc. If their IP address changes they just inform the DNS servers about this and you are directed still to the correct address when you try to connect since typing google.com forces your browser to connect to the DNS server first instead of directly to the last known IP address. The naming scheme we use to find IP addresses is called URL – Uniform Resource Locator. It’s the whole idea of .com and .net with whatever name attached to it appended with a slash that allows you to access a particular file or folder on those servers like http://www.embscomputerart.com/imgs/2dart/mummysunlight.jpg so you can get that file from my server.

Technically however even the dotted-decimal notation we used is not how real IP addresses are listed. They are actually represented in bytes, that’s not really important for our lesson, but it will help you understand the reason why the class InetAddress returns in byte arrays when using the method getAddress(). However for now we just need to know enough to program a server and client in java. Now because we are going to do that we need to know what port to use for our server. If we were making a web page server we’d use port 80 because that’s standard for web browsers to connect to so they can get pages, but we aren’t making one of those quite yet. So we’ll have to choose another port. But since there are so many ports that computers use for other things like email, gaming, etc., we want to make sure we pick a high number that is unlikely to be in use. Port numbers above 49141 are reserved for general private use. In our program we’ll use a short, but fairly high number, for testing like 1400 or whatever. Now a little warning here. If we open this port in our server and don’t close it properly in our code it will stay open even if we close our java program until we reboot the computer, so we’ll have to be sure to do that or we’ll get an error later. I’ll remind you of this when it is time.

Now that you have the necessary background information let’s get coding.

The Java API has a class called InetAddress which is the first class we’ll discuss. It’s helps us work with IP addresses. It is a representation of one essentially. The basic methods are…

byte getAddress() – returns a byte array like byte[] – remember how I said IP addresses are really bytes? They are sets of bytes or octets. And are just made easier for us by being switched to decimals like 127.0.0.1.

static InetAddress[]getAllbyName(String host) – returns a byte array of internet addresses for the hostname by using a DNS server to get the information. It throws an exception of UnknownHostException if there is a problem so we have to use a try/catch statement to use it.

static InetAddressgetByName(String host) – same thing but doesn’t return in an array.

String getCannonicalHostName() – returns full qualified hostname for the ip address.

String getHostAddress() – returns the IP address as a String.

String getHostName() – returns a DNS query’s information getting the hostname of the IP.

boolean isReachable(int timeout) – tests to see if the host is reachable in howevermany milliseconds.

String toString() – converts the IP address and hostname to a string. Pretty useful.

A good example program in Java for Dummies looks up IP addresses for hostnames. So you can enter say google.com and learn it’s IP address. Pretty useless to most people, but it helps you to understand how the InetAddress class works in java. I’ll write my own version which is simplified to help you out.

We’ll want to use a scanner class to get info from the user, otherwise we have to hardcode the request into our program. I don’t think I’ve covered the scanner class anywhere else so I’ll cover it quickly here. It’s just a class to make an object that takes the standard input from the console and uses it in our program. It’s simple. Example…

Scanner myscanner = new Scanner(System.in)

would create an object called myscanner of the Scanner class that used System.in during its construction. System.in is the standard input that a person uses to interact with a computer. In other words… the keyboard on the main terminal. Because we want our scanner to be accessible in any method we’ll declare it as static outside our methods but still within the class and that will make it a variable with global scope and therefore accessible by any method in that class. Of course to use a scanner and to use InetAddress we’ll do some imports. That’s all the background you’ll need so let’s get coding…

import java.util.Scanner;
import java.net.*;

public class IPFinder {
static Scanner myscanner = new Scanner(System.in);//creates a scanner for input from keyboard
static InetAddress[] addresses_array;//sets up an array to store IP addresses

public static void main(String[] args) {

String hostname;//sets up a String to store a hostname

System.out.println(“Enter a hostname and I’ll look up the IP address for you.”);

hostname = myscanner.nextLine();//this stores what user typed as a hostname

try{//we have to use a try/catch block because an error exception can occur
//if the host is not known (can not be found or whatever)
addresses_array = InetAddress.getAllByName(hostname);//we store the IP address…
//of the host in the array
System.out.println(addresses_array[0]);//we display the first element of the array…
//which contains the hostname and it’s IP address now.
}
catch (UnknownHostException e){//if that doesn’t work display this message.
System.out.println(“I’m sorry. That host is Unknown. Try again.”);
}

}
}

All the commentary is in the code. Pretty simple.

Now to create a server or client program we’ll have to cover the Socket and ServerSocket classes.

ServerSocket has these basic methods…

ServerSocket(int port) – basic constructor. Port number optional upon construction.

Socket attach() – listens for connections at the port it’s bound to. Once a connection is made the method is accessible returning a Socket object for communication with the client. In that way a ServerSocket class has the functionality of a regular Socket class too. It just doesn’t create the socket until a connection is made.

void bind (InetSocketAddress endpoint) – binds the server socket to the address supplied.

void close() – closes the ServerSocket – very very important. You must use this.

InetAddress getInetAddress – returns the address the ServerSocket is connected to. Remember how a InetAddress is just a way to represent IP addresses? There you go.

boolean isBound() – returns where the ServerSocket is bound to a port. Throws exception. Try/catch block necessary.

bolean isClosed() – same but reverse. Throws exception. Try/catch block necessary.

Okay that’s enough. You want to make a program that sends a message to the client when the client connects. That’s the heart of all network programs. In that way you could send a message or more which could be stored as a file by the client program or just read by the user of the client program or interpreted by the client program in a complex way like web browsers do to show webpages all nicely formatted. Let’s get coding…

import java.net.*;
import java.util.*;
import java.io.*;

public class SimpleServer {

static ServerSocket my_serversocket;//declares the ServerSocket object
static Socket my_socket;//declares the Socket object

public static void main(String[] args) {
int port = 1234;//declares and defines a port number

try {
my_serversocket = new ServerSocket(port);//defines the serversocket object with the port number
//the line above must be in a try/catch block
my_socket = my_serversocket.accept();

} catch (IOException e) {
System.out.println(“Error: Probably the server socket could not open the port”);
}

try {
PrintWriter out = new PrintWriter(my_socket.getOutputStream(), true);
out.println(“Hi Client. If you can read this then the server is working.”);
out.println(“The Server will now close the connection automatically. Thank you for connecting.”);
my_serversocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

The only real complicated thing there is the printwriter, which binds the output to the socket which only exists if a connection is made. The program will continue to run and wait for a connection until it’s shut down with ctrl-c or the stop button in your IDE. If a client connects it sends two messages as separate lines and closes itself.

To test our server we need a client. If we tried to connect to the server and port with just a web browser we wouldn’t get a correct connected an we’d have a null pointer exception which would collapse our server in a failure, so we’ll have to construct a better error routine for that later, but for now it’s testable, but we need a client program written to do it. Because of all the try/catch statements needed it is a little complicated but it’s not too bad.

import java.net.*;
import java.util.*;
import java.io.*;

public class SimpleClient {

public static void main(String[] args) {
int port = 1234;//this could be any port that the server is configured to use
Socket my_socket = getSocket(port);

try {
Scanner in = new Scanner(my_socket.getInputStream());//binds the scanner input…
//to whatever is being read by the socket as being sent from the server.
showServersMessages(in);//shows the messages from the server

} catch (IOException e) {
System.out.println(“The scanner could not be bound to the socket for some reason”);
}

}

private static void showServersMessages(Scanner in) {//this reads the first two lines
//sent by the server, we could make this a while statement to read everything sent
//if necessary
System.out.println(in.nextLine());
System.out.println(in.nextLine());
}

private static Socket getSocket(int port){//this gets our socket at a particular port…
//and ip address, we just set it up in this case for localhost testing.
Socket my_socket;
String host;
InetAddress ippa;

try {
ippa = InetAddress.getLocalHost();//we could use getByName(host) instead…
// if we wanted to ask the user for the hostname
try {
my_socket = new Socket(ippa, port);
return my_socket;
} catch (IOException e) {
e.printStackTrace();
}
}
catch (UnknownHostException e1) {
System.out.println(“The client does not know that host.”);
}
return null;
}
}

And there you have it. Run the server first, open a new terminal and run the client. And because the client is hardcoded to connect to localhost it will connect to the server, the server will send a message back to the client, the client will display that message and the server will shut itself down closing the port correctly so that it is no longer open and no longer listening for connections. We can do a lot with this basic idea. We can set up the server to stay active even after it closes the connection and then wait for another, we can make it connect to multiple clients simultaneously using threading, we can allow the clients user to specify the host and port, and since the information shared between the client and server can be stored and processed in any number of ways as the sockets can be bound bi-directionally to Scanners and FilePrinters we can use this program to send information that will stored in files on the server or client so we can exchange files between the computers in any format.  We’ll cover the threading next. Stay tuned.