Network Programming: What Is in This Chapter ?
Network Programming: What Is in This Chapter ?
Network Programming
There are many issues that arise when doing network programming which do not appear when
doing single program applications. However, JAVA makes networking applications simple
due to the easy-to-use libraries. In general, applications that have components running on
different machines are known as distributed applications ... and usually they consist of
client/server relationships.
Bank tellers (server) provide a service for the account owners (client)
Waitresses (server) provide a service for customers (client)
Travel agents (server) provide a service for people wishing to go on
vacation (client)
E.g., travel agents will become clients when they phone the airline to make a
reservation or contact a hotel to book a room.
In the general networking scenario, everybody can either be a client or a server at any time.
This is known as peer-to-peer computing. In terms of writing java applications it is similar to
having many applications communicating among one another.
E.g., the original Napster worked this way. Thousands of people all
acted as clients (trying to download songs from another person) as well
as servers (in that they allowed others to download their songs).
There are many different strategies for allowing communication between applications.
JAVA technology allows:
- 407 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
It is like a set of rules/steps for communication. The simplest example of a protocol is a phone
conversation:
Either way, there is an "expected" set of steps or responses involved during the initiation and
conclusion of the conversation. If these steps are not followed, confusion occurs (like when
you phone someone and they pick up the phone but do not say anything).
Computer protocols are similar in that a certain amount of "handshaking" goes on to establish
a valid connection between two machines. Just as we know that there are different ways to
shake hands, there are also different protocols. There are actually layered levels of protocols
in that some low level layers deal with how to transfer the data bits, others deal with more
higher-level issues such as "where to send the data to".
Computers running on the internet typically use one of the following high-level Application
Layer protocols to allow applications to communicate:
This is analogous to having multiple strategies for communicating with someone (in person, by
phone, through electronic means, by post office mail etc...).
- 408 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
This is analogous to having multiple ways of actually delivering a package to someone (Email,
Fax, UPS, Fed-Ex etc...)
Beneath that layer is a Network Layer for determining how to locate destinations for the data
(i.e., address). And at the lowest level (for computers) there is a Link Layer which actually
handles the transferring of bits/bytes.
When you write JAVA applications that communicate over a network, you are programming in
the Application Layer.
JAVA allows two types of communication via two main types of Transport Layer protocols:
TCP
a connection-based protocol that provides a
reliable flow of data between two computers.
guarantees that data sent from one end of the
connection actually gets to the other end and in the
same order
o similar to a phone call. Your words come out
in the order that you say them.
provides a point-to-point channel for applications
that require reliable communications.
slow overhead time of setting up an end-to-end
connection.
- 409 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
UDP
a protocol that sends independent packets of data,
called datagrams, from one computer to another.
no guarantees about arrival. UDP is not connection-
based like TCP.
provides communication that is not guaranteed
between the two ends
o sending packets is like sending a letter
through the postal service
o the order of delivery is not important and not
guaranteed
o each message is independent of any other
faster since no overhead of setting up end-to-end
connection
many firewalls and routers have been configured
NOT TO allow UDP packets.
Why would anyone want to use UDP protocol if information may get lost ?
Well, why do we use email or the post office ? We are never guaranteed that
our mail will make it to the person that we send it to, yet we still rely on those
delivery services. It may still be quicker than trying to contact a person via
phone to convey the data (i.e., like a TCP protocol).
Although a computer usually has a single physical connection to the network, data sent by
different applications or delivered to them do so through the use of ports configured on the
same physical network connection. When data is to be transmitted over the internet to an
application, it requires that we specify the address of the destination computer as well as the
application's port number. A computer's address is a 32-bit IP address. The port number is a
16-bit number ranging from 0 to 65,535, with ports 0-1023 restricted by well-known
applications like HTTP and FTP.
- 410 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
So, a URL can be used to represent the "location" of a webpage or web-based application. A
URL is really just a String that represents the name of a resource ... which can be files,
databases, applications, etc.. A resource name consists of a host machine name, filename,
port number, and other information. It may also specify a protocol identifier (e.g., http, ftp)
Here are some examples of URLs:
http://www.cnn.com/
http://www.apple.com/ipad/index.html
http://en.wikipedia.org/wiki/Computer_science
Here, http:// is the protocol identifier which indicates the protocol that will be used to obtain
the resource. The remaining part is the resource name, and its format depends on the
protocol used to access it.
a Host Name - The name of the machine on which the resource lives.
http://www.apple.com:80/ipad/index.html
In JAVA, there is a URL class defined in the java.net package. We can create our own URL
objects as follows:
JAVA will "dissect" the given String in order to obtain information about protocol, hostName,
file etc....
Due to this, JAVA may throw a MalformedURLException ... so we will need to do this:
try {
URL webPage = new URL("http://www.apple.com/ipad/index.html");
} catch(MalformedURLException e) {
...
}
- 411 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
try {
URL webPage = new URL("http","www.apple.com",80,"/ipad/index.html");
} catch(MalformedURLException e) {
...
}
If you take a look at the JAVA API, you will notice some other constructors as well.
The URL class also supplies methods for extracting the parts (protocol, host, file, port and
reference) of a URL object. Here is an example that demonstrates what can be accessed.
Note that this example only manipulates a URL object, it does not go off to grab any web
pages:
import java.net.*;
http://www.apple.com:80/ipad/index.html
protocol = http
host = www.apple.com
filename = /ipad/index.html
port = 80
ref = null
After creating a URL object, you can actually connect to that webpage and read the contents of
the URL by using its openStream() method which returns an InputStream. You actually read
from the webpage as if it were a simple text file. If an attempt is made to read from a URL that
does not exist, JAVA will throw an UnknownHostException
- 412 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
Example:
Here is an example that reads a URL directly. It actually reads the file on wikipedia and
displays it line by line to the console. Notice that it reads the file as a text file, so we simply
get the HTML code. Also, you must be connected to the internet to run this code:
import java.net.*;
import java.io.*;
The output should look something like this, assuming you could connect to the webpage:
<!DOCTYPE html>
<html class="client-nojs" lang="en" dir="ltr">
<head>
<meta charset="UTF-8"/>
<title>Computer science - Wikipedia</title>
<script>document.documentElement.className =
document.documentElement.className.replace( /(^|\s)client-nojs(\s|$)/, "$1client-js$2"
);</script>
<script>(window.RLQ=window.RLQ||[]).push(function(){mw.config.set({"wgCanonicalNamespa
ce":"","wgCanonicalSpecialPageName":false,"wgNamespaceNumber":0,"wgPageName":"Computer
_science","wgTitle":"Computer
science","wgCurRevisionId":771021423,"wgRevisionId":771021423,"wgArticleId":5323,"wgIs
Article":true,"wgIsRedirect":false,"wgAction":"view","wgUserName":null,"wgUserGroups":
["*"],"wgCategories":["Pages using web citations with no URL","Pages using citations
with accessdate and no URL","Webarchive template wayback links","Pages using ISBN
magic links","Wikipedia pages semi-protected against vandalism","Wikipedia
...
- 413 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
Example:
Here is a modification to the above example that reads the URL by making a URLConnection
first. Since the tasks of opening a connection to a webpage and reading the contents may
both generate an IOException, we cannot distinguish the kind of error that occurred. By
trying to establish the connection first, if any IOExceptions occur, we know they are due to a
connection problem. Once the connection has been established, then any further
IOException errors would be due to the reading of the webpage data.
import java.net.*;
import java.io.*;
- 414 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
The client typically "uses" the service and then displays results to the
user. Normally, communication between the client and server must be
reliable (no data can be dropped or missing):
- 415 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
The port number is used as the server's location on the machine that the
server application is running. So if a computer is running many different
server applications on the same physical machine, the port number
uniquely identifies the particular server that the client wishes to
communicate with:
The client and server may then each read and write to the socket bound to its end of the
connection.
In JAVA, the server application uses a ServerSocket object to wait for client connection
requests. When you create a ServerSocket, you must specify a port number (an int). It is
possible that the server cannot set up a socket and so we have to expect a possible
IOException. Here is an example:
ServerSocket serverSocket;
try {
serverSocket = new ServerSocket(SERVER_PORT);
}
catch(IOException e) {
System.out.println("Cannot open server connection");
}
- 416 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
The server waits for an incoming client request through the use of the accept() message:
Socket aClientSocket;
try {
aClientSocket = serverSocket.accept();
}
catch(IOException e) {
System.out.println("Cannot connect to client");
}
When the accept() method is called, the server program actually waits
(i.e., blocks) until a client becomes available (i.e., an incoming client
request arrives). Then it creates and returns a Socket object through
which communication takes place.
Once the client and server have completed their interaction, the socket
is then closed:
aClientSocket.close();
Only then may the next client open a socket connection to the server. So, remember ... if one
client has a connection, everybody else has to wait until they are done:
So how does the client connect to the server ? Well, the client must know the address of the
server as well as the port number. The server's address is stored as an InetAddress object
which represents any IP address (i.e., an internet address, an ftp site, local machine etc,...).
If the server and client are on the same machine, the static method getLocatHost() in the
InetAddress class may be used to get an address representing the local machine as follows:
- 417 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
Once again, a socket object is returned which can then be used for communication.
Here is an example of what a local host may look like:
cr850205-a/169.254.180.32
InetAddress.getByName("169.254.1.61");
InetAddress.getByName("www.scs.carleton.ca");
So how do we actually do communication between the client and the server ? Well, each
socket has an inputStream and an outputStream. So, once we have the sockets, we simply
ask for these streams … and then reading and writing may occur.
try {
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
}
catch(IOException e) {
System.out.println("Cannot open I/O Streams");
}
Normally, however, we actually wrap these input/output streams with text-based, datatype-
based or object-based wrappers:
You may look back at the notes on file I/O to see how to write to the streams. However, one
more point ... when data is sent through the output stream, the flush() method should be sent
to the output stream so that the data is not buffered, but actually sent right away.
- 418 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
Example:
Let us now take a look at a real example. In this example, a client will attempt to:
1. connect to a server
2. ask the server for the current time
3. ask the server for the number of requests that the server has handled so far
4. ask the server for an invalid request (i.e., for a pizza)
Here is the server application. It runs forever, continually waiting for incoming client requests:
try {
// Wait for an incoming client request
socket = serverSocket.accept();
// At this point, a client connection has been made
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
- 419 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
} catch(IOException e) {
System.out.println("SERVER: Error connecting to client");
System.exit(-1);
}
// Read in the client's request
try {
String request = in.readLine();
System.out.println("SERVER: Client Message Received: " + request);
if (request.equals("What Time is It ?")) {
out.println(new java.util.Date());
counter++;
}
else if (request.equals("How many requests have you handled ?"))
out.println(counter++);
else
System.out.println("SERVER: Unknown request: " + request);
} catch(IOException e) {
System.out.println("SERVER: Error communicating with client");
}
}
}
import java.net.*;
import java.io.*;
- 420 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
- 421 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
Let us look at the same client-server application, but by now using DatagramSockets and
DatagramPackets. Once again, the server will be in a infinite loop accepting messages,
although there will be no direct socket connection to the client. We will be setting up a buffer
(i.e., an array of bytes) which will be used to receive incoming requests.
The code for packaging and sending an outgoing packet involves creating a DatagramSocket
and then constructing a DatagramPacket. The packet requires an array of bytes, as well as
the address and port in which to send to. A byte array can be obtained from most objects by
sending a getBytes() message to the object. Finally, a send() message is used to send the
packet:
byte[] sendBuffer;
DatagramSocket socket;
DatagramPacket packetToSend ;
The server code for receiving an incoming packet involves allocating space (i.e., a byte array)
for the DatagramPacket and then receiving it. The code looks as follows:
byte[] recieveBuffer;
DatagramPacket receivePacket;
We then need to extract the data from the packet. We can get the address and port of the
- 422 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
In this case the data sent was a String, although it may in general be any object. By using
the sender's address and port, whoever receives the packet can send back a reply.
Example:
Here is a modified version of our client/server code ... now using the DatagramPackets:
import java.net.*;
import java.io.*;
- 423 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
Notice that only one DatagramSocket is used, but that a new DatagramPacket object is
created for each incoming message. Now let us look at the client:
- 424 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
import java.net.*;
import java.io.*;
public PacketClientProgram() {
try {
localHost = InetAddress.getLocalHost();
} catch(UnknownHostException e) {
System.out.println("CLIENT: Error connecting to network");
System.exit(-1);
}
}
- 425 -
COMP1406 - Chapter 12 - Network Programming Winter 2017
try {
byte[] receiveBuffer = new byte[INPUT_BUFFER_LIMIT];
DatagramPacket receivePacket = new DatagramPacket(receiveBuffer,
receiveBuffer.length);
socket.receive(receivePacket);
- 426 -