LAB 10 - Sockets - Networking with java
Goal
- Develop a simple calculator for computing the 4 basic operations(+,-,*,/) employing java network capability.
The client program will take the input data, send data to the server program for the computation, receive back from the server the result and display the result. The server program will compute the operation. - Create a class Operation for storing 2 numbers, the kind of operation, the result of the operation, and methods for computing +,-,*,/
- A client program, called CalculateClient.java will take three arguments from the command line. Two numbers and the operation. It creates an object instance of the class Operation, initializing the 2 numbers and the kind of operation. The client program will serialize the object created, and send it to the server.
- Develop a server program, called CalculateServer.java for receiving the serialized object from CalculateClient, calculating the result, serializing the object again and send it back to client.
- Once CalculateClient receive back the Operation object back, it should be capable to deserialize it, take the result and display it
Intro
Before data is sent across the Internet from one host to another, it is split into packets of varying but finite size called datagrams. Datagrams range in size from a few dozen bytes to about 60,000 bytes. Anything larger, and often things smaller, must be split into smaller pieces before it can be transmitted. The advantage of this scheme is that if one packet is lost, it can be retransmitted without requiring redelivery of all other packets. Furthermore, if packets arrive out of order, they can be reordered at the receiving end of the connection.
Fortunately, packets are invisible to the Java programmer. The host's native networking software splits data into packets on the sending end and reassembles packets on the receiving end. Instead, the Java programmer is presented with a higher-level abstraction called a socket. The socket represents a reliable connection for the transmission of data between two hosts. It isolates you from the details of packet encodings, lost and retransmitted packets, and packets that arrive out of order. A socket performs four fundamental operations:
1. Connect to a remote machine
2. Send data
3. Receive data
4. Close the connection
A socket may not be connected to more than one host at a time. However, a socket may both send data to and receive data from the host to which it's connected.
What is a Socket?
A socket is one end-point of a two-way communication link between two programs running on the network. Socket classes are used to represent the connection between a client program and a server program. Sockets are of two kinds: ordinary sockets and server sockets. A server socket is never used for transmission of information. Its sole purpose is to listen for incoming connection requests. When a client process wishes to make a connection with a server, it first constructs an ordinary socket and then it asks for a connection with the server. When a server socket receives a connection request, it constructs an ordinary socket with an unused port number which completes the connection. The server socket then goes back to listening for connections. Once the connection is established, the two connected sockets can communicate with each other using ordinary read and write operations in either direction. Java encapsulates the concept of an ordinary TCP socket with the class Socket, and the concept of a server socket with the class ServerSocket. Input to and output from a socket is encapsulated in Java using the InputStream and OutputStream classes, respectively.
How I open a Socket? - Client side
If you are programming a client, then you would open a socket like this:
Socket MyClient;
myClient = new Socket("Machine name", PortNumber);
Where Machine name is the machine you are trying to open a connection to,
and PortNumber is the port (a number) on which the server you are trying
to connect to is running. When selecting a port number, you should note that
port numbers between 0 and 1,023 are reserved for privileged users
(that is, super user or root). These port numbers are reserved for
standard services, such as email, FTP, and HTTP. When selecting a port
number for your server, select one that is greater than 1,023!
In the example above, I didn't make use of exception handling, however,
it is a good idea to handle exceptions. (From now on, all our code will
handle exceptions!) The above can be written as:
Socket MyClient;
try {
MyClient = new Socket("Machine name", PortNumber);
}
catch (IOException e) {
System.out.println(e);
}
How I open a Socket? - Server side
The server program begins by creating a new ServerSocket object to listen on a specific port (see the statement in bold in the following code segment).
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Could not listen on port: 4444");
System.exit(-1);
}
ServerSocket is a java.net class that provides a system-independent implementation of the server side of a client/server socket connection. The constructor for ServerSocket throws an exception if it can't listen on the specified port (for example, the port is already being used).
If the server successfully connects to its port, then the ServerSocket object is successfully created and the server continues to the next step--accepting a connection from a client
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);
}
The accept method waits until a client starts up and requests a connection on the host and port of this server (in this example, the server is running on the hypothetical machine taranis on port 4444). When a connection is requested and successfully established, the accept method returns a new Socket object which is bound to a new port. The server can communicate with the client over this new Socket and continue to listen for client connection requests on the ServerSocket bound to the original, predetermined port.
How I can send and receive with Sockets?
These methods also allow for the creation of input and output streams.
InputStream getInputStream()throws IOException: This method returns an InputStream that allows the Socket to receive data across the TCP connection. An InputStream can be buffered or standard.
OutputStream getOutputStream()throws IOException This method returns an OutputStream that allows the Socket to send data across the TCP connection. An OutputStream should be buffered to avoid lost bytes, especially when the Socket is closed.
How do I close the sockets?
You should always close the output and input stream before you close the socket.On the client side:
try {
output.close();
input.close();
MyClient.close();
catch (IOException e) {
System.out.println(e);
}
On the server side:
try {
output.close();
input.close();
serviceSocket.close();
MyService.close();
}
catch (IOException e) {
System.out.println(e);
}
How your code will look like
Client -For the CalculateClient:
Socket socket = new Socket(remoteIP,PORT); // write the operation ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); oos.writeObject(operation); oos.flush(); // read result ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); Operation resultOperation = (Operation) ois.readObject();
Server -For the CalculateServer:
// get the operation ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); Operation in = (Operation) ois.readObject(); // computational part Operation out = CalculateResult(in); // write result ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); oos.writeObject(out);
Running the programs
You must start the server program first. To do this, run the server program using the Java interpreter, just as you would any other Java application. Remember to run the server on the machine that the client program specifies when it creates the socket. Next, run the client program. Note that you can run the client on any machine on your network; it does not have to run on the same machine as the server. If you are too quick, you might start the client before the server has a chance to initialize itself and begin listening on the port. If this happens, you will see a stack trace from the client. If this happens, just restart the client.