Download Tutorial 3

Document related concepts
no text concepts found
Transcript
MT311 (Oct 2006)
Java Application Development
Tutorial 3
Exceptions Handling,
Streamed I/O,
Multithreading and
Network Programming
Tutor Information




Edmund Chiu (Group 1)
Email: [email protected] OR
[email protected]
Please begin your email subject with [MT311]
Webpage: http://geocities.yahoo.com/gianted
PART I
Exceptions Handling
Exception
Try, catch and finally
Throw statement and
Throws clause
Exceptions Handling

Exceptional handling is a systematic way to separate
the normal flow of a program from special handlers of
abnormal conditions.
–
–

Main program handles key computing logics
When an error occurs, the control is transferred to error
handler
Exceptions are an integral part of Java programming
–
–
Exceptions may be generated at runtime (e.g. divide by zero
error)
Many methods also throw exceptions, especially those deal
with I/O and networks
Try-Catch Blocks

The basic exception handling technique:
1) Enclose the code that may generate an exception
with a try-block
2) Handle the exception(s) that you want to deal with
in a catch-block
try {
<statements with possible errors>
} catch (<ExceptionType> <exceptionVar>) {
<action statements>
}
Flow Control in Try-Catch Blocks





When the program executes and a statement in the try
block causes an error, the control will be transferred to
catch blocks
The error in try block will be matched with the
exception type in the parentheses in the catch block
When the exception is matched, the corresponding
handler will be executed
After the exception handler finishes its work, the control
will be passed to the point immediate after the catch
blocks
If no match is made, the program halts and give out
error
Multiple Catch-Block

A try block can be followed by more than one catchblocks
–
–
–
the exception will be checked against in sequence
whenever a match is made, the handler code is executed, the
control will be passed to the point immediate after the catch
blocks
In general, we place the blocks from specific exceptions to
more general ones, example:
try { // some errors occur here
} catch (FileNotFoundException e) { // coding here
} catch (IOException e) { // do something here
} catch (Exception e) { // do other things here
} finally { // always run these codes }
Finally Block

After handling the exception, the control will not be
back to the point of original exception
–

This may case resource leaks, e.g. opened file handler not
closed
Finally block is used to handle the situation
–
–
optional block, must appear if no catch block is defined for a
try block
no matter which or none of the exception handler has been
executed (even if the try block is exited through return, exit or
etc.), the control will be passed to finally block
Create an Exception

Normally, exceptions are generated when the system
detects errors, but you can also throw an exception by
using throw. Example:
throw new RuntimeException(“This is my own fault”);

The throw statement can be used in everywhere
–
–
One of the use of throwing a new exception is throwing a userdefined exception
The other use of the throw keyword is throwing an exception in
the catch block. We call it re-throw of an exception. Example:
catch (IOException e) { // do something
throw e; }
Re-throwing exception is used when there may be further error
handling code needed in the following catch blocks.
Exceptions Hierarchy

Exception classes can be inherited like ordinary
classes, examples:
–
–



NumberFormatException extends RuntimeException
FileNotFoundException extends IOException
Likewise, each exception class has their constructors
The user-defined exception can extend an appropriate
Java exception
When an exception superclass is caught, all its
subclasses will also be caught
Checked vs. Unchecked Exceptions

Exceptions in Java can be checked or
unchecked
–
–
–
Checked exceptions must be caught in your
application (e.g., all IO exceptions, SQL exceptions)
Unchecked exceptions include runtime numeric
exceptions like illegal number of arguments, array
index out of bound, null pointer exceptions and etc.
A class cannot be compiled if a method throws a
checked exception but not caught
Throws Clause

Throws clause can be used in a method to
propagate the uncaught checked exceptions to
the caller
–
Example:
void myMethod throws Exception1, Exception2
{ … }
–
The thrown exception should be caught in the
method or class using this method; otherwise, the
program cannot be compiled
Pros and Cons of
Exception Handling

Advantages
–
–
–

Separate the exceptional conditions from the normal flow of
the program, allow you to construct a cleaner program
One single handler can handle the same type of errors thrown
out from different points in the program
Ensure no error is ignored intentionally or unintentionally.
Checked exception has to be handled and cannot be
overlooked.
Disadvantages
–
–
Exceptions propagated multiple levels become hard to trace
Code with excessive error handling may not be optimized
effectively.
Part II
Streamed I/O
InputStream
/OutputStream,
Reader/Writer
What is a Stream

Most of Java’s IO interactions are implemented using
streams.
–
–
–
–
A buffer that reads/writes sequentially
InputStreams are used for read-only operations
OutputStreams are used for write-only purposes
No read-write streams is available in Java

–
However, there are some other read/write implementation that
supports read and write using the same object (e.g.
RandomAccessFile)
Java streams will be blocked if


There are no data in an inputstream
The buffer in an outputstream is full
InputStream and OutputStream

Available methods in
InputStream
–
–
–
–
read() reads a single byte
from the stream. –1 was
read if the stream has
reached the end
read(byte[]) reads data
into an array of bytes
available() returns the
number of bytes can be
read
close() closes the stream

Available methods in
OutputStream
–
–
–
–
–
write() writes a single byte to
the stream
write(byte[]) writes the entire
byte array to the stream
write(byte[], int, int) writes a
portion of a byte array, from a
specific position, read n
bytes.
flush() forces all bytes in
buffer to the stream
close() closes the stream
Java InputStreams and
OutputStreams
FileInputStream and
FileOutputStream

Instead of using InputStream and OutputStream, we
usually use FileInputStream and FileOutputStream
–

FileInputStream and FileOutputStream can open a file in an
easy way:
FileInputStream in = new FileInputStream(filename);
FileOutputStream out = new FileOutputStream(filename);
File copying can be easily implemented by reading a
byte then writing it out immediately
byte b = in.read();
out.write(b);
import java.io.*;
public class FileCopy {
public static void main(String[] args) {
if (args.length != 2) {
throw (new IllegalArgumentException(
"Usage: FileCopy <src> <destination>"));
}
FileInputStream in = null;
FileOutputStream out = null;
try { // open the files
in = new FileInputStream(args[0]);
out = new FileOutputStream(args[1]);
while (in.available() > 0) { out.write(in.read()); }
} catch (IOException e) {
System.out.println(e);
} finally { // close the files
try {
if (out != null) out.close();
if (in != null) in.close();
} catch (IOException e) { System.out.println(e); }
}
}
}
Readers and Writers for
Character Handling

Byte stream and characters are alike
–
–

Byte steams operate on bytes
Character streams operate on characters
(multilingual)
The file copying program can be implemented
using FileReader and FileWriter easily
–
The only difference from the previous example is
the variables in and out is now the FileReader and
FileWriter
Java Readers and Writers
Data Streams


Byte streams and character streams deals with one
single type of data (bytes/characters)
Java can also handle primitive data types (and even
Strings) such as int and double using DataInputStream
and DataOutputStream
–

The marshalling and unmarshalling between bytes and
primitive data types are hidden behind the two classes
Sample methods
–
readInt, readDouble, readChar, readUTF(for String) and etc.
Object Serialization


Java can also handle read/write an Object from/to a
stream through ObjectInputStream and
ObjectOutputStream using readObject and writeObject
However, not all object types can be read/written in a
stream
–
–
–
–

Example, we can’t write a Stream into another stream
We call an object that can be read from/written to a stream
serializable
Normally, a serializable object contains viewable data only
All variables in a serializable object are either serializable or of
primitive data types
Object serialization is useful to save and write an entire
object.
Sources and Streams

You can create different types of streams from
the same source
–

You can create a byte stream on a file and also
another character stream on the same file at the
same time
You can also connected a stream to different
sources, for example, a file or a network
connection
Chaining Streams

For example,
FileReader provides an easy way to read characters
– BufferedReader provides a readLine method to read lines
– We can simply chain up the FileReader and BufferedReader
so that we can read lines from a file
BufferedReader input =
new BufferedReader(new FileReader(filename));
–

We can chain up readers/writers and streams in a very
flexible way
LineNumberReader lineReader =
new LineNumberReader(new BufferedReader(
new FileReader(filename)));
import java.io.*;
public class LineNumber {
public static void main(String[] args) {
if (args.length != 1)
throw (new IllegalArgumentException(
"LineNumber: LineNumber <file>"));
LineNumberReader lnReader = null;
String line;
try { // create a LineNumberReader from the file
lnReader = new LineNumberReader(
new BufferedReader(new FileReader(args[0])));
while ((line = lnReader.readLine()) != null) {
System.out.println(" " +
lnReader.getLineNumber() + ": " + line);
}
} catch (IOException e) {
System.out.println("File error: " + e);
} finally {
try {
if (lnReader!= null) lnReader.close();
} catch (IOException e) {
System.out.println("File close error.");
}
}
}
}
Part THREE
Multithreading
Multithreading
Synchronization
Wait & Notify
Concept of Multithreading


Multithreading is the capability for
programmers to let different parts of the
program execute at the same time
In a typical application, there is usually more
than one thread working
–
Example: Web browser




Load the HTML text
Load the embedded image
a thread listening user input (mouse and/or keyboard)
etc…
Java Threads





In Java, a thread is a point of process which has its
own run-time resources support
A thread executes its instructions line-by-line
Concurrency occurs when multiple threads run
together
Static method main defines the main thread of the
execution
A thread is created by:
–
–
a class extending the thread class
a class implements the runnable interface
Class Thread

Class Thread is from the package java.lang
–
–

A user-defined thread should extend Java’s thread
class
–

Constructor Thread(String threadName) will create a thread
with the name “threadName”
Constructor Thread( ) will create a thread with the name
“Thread-##” where ## is a number
public class MyThread extends Thread { … }
The instruction that a thread is to be accomplished is
placed inside the method run, which you need to
override in your own thread class
Start Running a Thread


Though the main body of a thread is the run method,
you will never call it directly
To start the execution of a thread, we need to call the
start method
–
–
–
–
A thread of your class is created first
Call start method to makes the method ready to run
Example: new MyThread().start( )
start method returns immediately – it will not wait till the end of
the thread execution – the caller and the thread is executing
concurrently
start method can only be called once, repeated call incurs
IllegalThreadStateException
Simple Thread Example
public class SimpleThread1 extends Thread {
private String str;
public SimpleThread1 (String str) { this.str = str; }
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(i + " " + str);
try { // sleep for a random interval
Thread.sleep((long)(Math.random() * 500));
} catch (InterruptedException e) {}
}
System.out.println("God is my " + str);
}
public static void main(String[] args) {
new SimpleThread1 ("Strength").start();
new SimpleThread1 ("Shield").start();
new SimpleThread1 ("Rock").start();
}
}
Runnable Interface

As Java has no multiple inheritances, we cannot
extend Thread if it has already extended other class
–
–

However, we can implements multiple interfaces
Thus, Java provides another way to implement threads –
through Runnable interface
In a Runnable interface,
–
–
You need to override the run method which contains the
instruction for the thread
You need to construct a thread using a runnable object
Runnable a = new SimpleRunnable();
Thread t = new Thread(a);
t.start();
Simple Runnable Example
public class SimpleRunnable1 implements Runnable {
private String str;
public SimpleRunnable1(String str) { this.str = str; }
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(i + " " + str);
try { // sleep for a random interval
Thread.sleep((long)(Math.random() * 500));
} catch (InterruptedException e) {}
}
System.out.println("God is my " + str);
}
public static void main(String[] args) {
new Thread(new SimpleRunnable1("Strength")).start();
new Thread(new SimpleRunnable1("Shield")).start();
new Thread(new SimpleRunnable1("Rock")).start();
}
}
Life Cycle of a Thread
born
start( )
notify( )
notifyAll( )
I/O complete
ready
Timeslice expired
yield( )
Assign processor
running
wait( )
I/O
complete
sleep( )
waiting
Sleep period expires
sleeping
dead
blocked
Concurrency and Sleep

Within a thread, the instructions are executed
sequentially
–
–

While multiple threads are running together, they may
interleave.
You may notice that the result of the previous examples may
be different each time
This may be also due to the threads “sleep” for a
random period in the loops
–
–
Thread.sleep((long) (Math.random() * 500));
When a thread sleeps, other threads can still proceed
Only the current thread can be told to sleep, so it is a static
method
Thread Interleaving example

If we change the run method in the previous
example:
public void run() {
for (int i = 0; i < 10000; i++) {
if (i % 100 == 0)
System.out.println(str + " " + i);
}
System.out.println("God is my " + str);
}
We can see the interleaving effect of the
threads is independent of the sleep method
Sample Result of the Modified
Example
Importance of Synchronization

In multithreading, a variable may be accessed by more
than one thread simultaneously
–
–
no problem if read access only
problem occurs when modification is involved






Thread 1 reads A = 5
Thread 2 reads A = 5
Thread 1 increases the variable by 1, A = 6
Thread 2 increases the variable by 1, A = 6
Instead of increasing the variable every time when a thread is
called, the second thread just updated the old version of the
variable
To make an object thread safe, you need to
synchronize all data that is shared by different threads
Synchronized Methods

Java provides the keyword synchronized to lock up an
object so that only one thread can access that object
when the method is called
–
–
–

Example: public synchronized void set (int data)
synchronized method enforces the exclusive access to the
respective object
the thread unable to access the object will go to the “blocked”
state
Synchronized keyword can also apply to lock up a
specific variable within a block of codes
–
Example: sychronized(counter) { counter.inc(); }
Deadlock and Notification

Deadlock may occur when the threads are sharing
more than one synchronized objects
–

Example: Thread1 has taken object A and is now waiting for
object B, but Thread2 has taken object B and is now waiting
for object A. Deadlock occurs.
In Java, we avoid the case by using thread notification
–
–
The thread who cannot get all synchronized objects will go into
waiting status, which will temporarily release its exclusive
access to the object
When the thread finishes its work on a synchronized object, it
will notify other threads so that they can try to reacquire the
access to the object
Wait and Notify


Both methods are instance methods of any object
When wait is called, the thread will be blocked and
added into the object’s waiting list
–
–
–

wait gives up the lock of the object
it should be called within synchronized method, otherwise, an
IllegalMonitorStateException may occur
InterruptedException may occur while the thread is waiting
Once the notify method of the object is called, one of
the threads on the list will be chosen to return to the
ready state again
Notify and NotifyAll

When notify method is used, only one thread of
consumer can be brought to ready state
–

JVM implementation determines which thread to be
brought
If you want to notify more than one thread that
are waiting, you need to use notifyAll method
on the object
–
all threads return to ready state and compete for the
lock
Example of Thread-Safe Data Store
class DataStore {
private int data;
private boolean ready = false;
public synchronized int get() {
while (! ready) {
wait(); // no data, wait for it
}
ready = false; // data ready, we consume it
notifyAll(); // data consumed, notify all waiting producers
return data;
}
public synchronized void put(int v) {
while (ready) {
wait(); // data not consumed yet, wait
}
data = v;
ready = true;
notifyAll(); // data ready, notifying all waiting consumers
}
}
Part IV
Network Basic
IP, DNS, TCP and
UDP
IP Packet and IP

Packets are basic unit of delivery
–
–

Packet header stores the source and destination of the unit
(like a letter envelop front)
Packet data is the content
IP address is used to identify a computer in the
network
–
–
consists of 4 integers in the range of 0 to 255, separated by 3
dots. Example: OUHK homepage: 202.40.157.186
127.0.0.1 is the loop-back address to test your network
application
Different types of IP address

Five classes of IP address
–
–
–
–
–

Class A: 0.0.0.0 – 127.255.255.255 (Leftmost bits: 0xxx)
Class B: 128.0.0.0 – 191.255.255.255 (Leftmost bits: 10xx)
Class C: 192.0.0.0 – 223.255.255.255 (Leftmost bits: 110x)
Class D: 224.0.0.0 – 239.255.255.255 (Leftmost bits: 1110)
Class E: 240.0.0.0 – 255.255.255.255 (Leftmost bits: 1111)
Private addresses range
–
–
–
Class A: 10.0.0.0 – 10.255.255.255
Class B: 172.16.0.0 – 172.31.255.255
Class C: 192.168.0.0 – 192.168.255.255
Network Address, Node Address
and Subnet Mask

Each IP address is made up of two parts.
–
–

Leading part (network part) identifies a particular network
Trailing part (node/host part) determines a specific node of the
network.
The network address and node address can be
determine by subnet mask
–
–
Suppose the IP is 10.0.0.11 and the subnet mask is
255.255.255.252
By bit-wise conjunction of 252 (1111 1100) with 11 (0000 1011),
we obtain the last digit for the network address: 8 (0000 1000)
(10.0.0.8)
IP Ports

Network ports are used to specify the service request
on the host
different services (e.g. FTP and WWW) have their own port
number
logical entities numbered from 0 to 65535
– 0 to 1023 are reserved for common system services.
E.g., FTP – port 21, WWW – port 80
–

Combination of host name (or IP address) and port
number can uniquely specify the host and server you
want to talk to.
Uniform Resource Locators (URLs)


URL are the pointers to the resources on the WWW
A URL consists of:
<protocol>://<hostname>:<port_no>/
<resources_location>
–
–
–
–
–
protocol: the protocol to be used to get the resources, the most
common ones are http and ftp
hostname: the host which holds the resources
port number: if omitted, default number is used
resource location: resource may be a file, a directory or even a
query to database
Example: http://plbpc001.ouhk.edu.hk/~mt311
Domain Name Service (DNS)

A host name consists of two parts
–
–
–
the name of the domain
unique name identifies a computer within the
domain
Example:



all computers in OUHK are under the domain ouhk.edu.hk,
the host that serves the homepage is www.
Mapping of host names to IP address is stored
in Domain Name Servers (DNS)
Transport Protocols


Internet protocol (IP) only defines the basic
organization of the network
Transport protocol deal with constructing and delivering
packets on the network
–
–
Transmission Control Protocol (TCP) creates a virtual
dedicated and continuous connection between the
communicating parties.
User Datagram Protocol (UDP) is a connectionless protocol.
It creates datagrams that includes destination information and
data content. The datatgrams will find its way to the destination
eventually. Each datagram is limited to a size of 64KB
More about TCP and UDP

TCP
–
–
–
–

Connection Oriented (Stream) Socket
Like a circuit (stream) is connecting two sockets (computer)
Sockets are created exclusively for the connection of the two
computers
No need to specify the destination
UDP
–
–
–
–
Connectionless (Datagram) Socket
Like a postal system
Datagram = Envelops
Datagram Socket = address – keep a record of IP and port number
Multiple receivers and receiving messages from different addresses is
allowed
Destination must be specified
Comparing TCP and UDP
TCP
UDP
In pair
Yes
No
Dedicated link
Yes
No
Messages in order
Yes
No
Delivery Guarantee
Yes
No
Not limited
64KB per packet
(Designed for short data)
Higher
(dedicated
connection)
Lower
(connection not dedicated,
less overhead)
no data lost even
buffer is full
Datagram truncated if
buffer is full
Data Size
Computational cost
Receiver Buffer
Why UDP is used

Guarantee delivery may be a nuisance in some
application
–

For example, in a real-time video streaming
application, it is better to ignore a small chunk of
missing data than holding up the entire streaming
and wait for the resend of the missing data
TCP connections are one-to-one while a single
UDP can address multiple recipients using
multicast and/or broadcast addresses.
Transport Protocols Built on Top of
TCP and UDP

HTTP (Hypertext Transfer Protocol)
–
–

FTP (File Transfer Protocol)
–
–

For transferring data from a place to another
Use port 21
SMTP (Simple Mail Transfer Protocol)
–
–

For transferring data in the World Wide Web
Use port 80
For sending email over the Internet
Use port 25
POP (Post Office Protocol)
–
–
(POP3) For transferring accumulated email from the host to
the connected clients
Use port 110
Structure of Network Application

Client-side networking
–
–

Server-side networking
–
–

You are given a specific server and you are concerned with
how to communicate with the server
For example, you may write a network program to connect to a
Web server
You are creating a server that accepts connection requests
from clients
For example, you may write a network program to provide
network services to the world
Usually, we will do both client-side and server-side
networking when we are developing a new network
application
Flow of Client-Side Application
1.
Identify the target server and the service
–
2.
3.
4.
5.
IP address and port number
Create a connection to the target server and service
Wait for the server to respond to the connection
request
Create the I/O streams for the communication. Read
and write to the connection and perform the
application logic
Close the streams and connection when the
communication is completed
Flow of Server-Side Application
1.
2.
3.
4.
Listen for client requests on a particular port
When a communication request arrives,
create the connection
Create the I/O streams for the
communication. Communicate with the client
using the client connection
Close the streams and the client connection
when the communication is completed.
Part V
Network Programming in Java
InetAddress, URL,
Stream Sockets,
Multi-threaded Server,
Datagram Socket
InetAddress Class


java.net.InetAddress is used to deal with IP addresses
3 static methods can be used to resolve the IP address of
a host
–
–
–
InetAddress.getByName(String hostname) – for first IP (as an
InetAddress object)
InetAddress.getAllByName(String hostname) – for multiple IP (as
an InetAddress array). Multiple IPs are used to distribute
workload for a service among the server machines
InetAddress.getLocalHost( ) – for localhost (as an InetAddress
object)
URL in Java

The class in Java to manipulate URL is: java.net.URL
–
–
–
–
–
–
–
One constructor accepts String parameter
MalformedURLException is thrown if the input text is not a valid
format of URL
try { URL myURL = new URL("http://www.ouhk.edu.hk");
} catch (MalformedURLException e) { e.printStackTrace(); }
We can get the host part of the URL using method getHost()
The port of the URL can be retrieved using method getPort(); the
method will return –1 if no port is listed out in the URL
The file part of the URL can be retrieved using method getFile()
If format is valid, exception will not be thrown even it is obvious that
the resource does not exits.
Example: http://abcd.efg.ijk
HTTP Client


We can create a HTTP client using connecting
to existing Web server
We send different HTTP command to get
information from the server
–
–
HEAD gets the information about a file on the server
Example: HEAD test.html HTTP/1.0 retrieve the file
information using HTTP version 1.0 standard
GET gets the actual file from the server
Example: GET test.html HTTP/1.0
Flow of HTTP Client
1.
2.
3.
4.
5.


Read a URL and break it down into server, port and
filename components
Open a Socket connection to the HTTP server
Send an HTTP GET command to request the file from
the server
Read the response from the server
Close the connection
You need to open the I/O streams throughout the
process
A Socket connection uses TCP to connect to the
server. Details will be given in later slides.
Actual Code for HTTP Client
import java.net.*;
import java.io.*;
public class PageLoader {
protected String host, file;
protected int port;
protected Socket socket = null;
protected Writer writer = null;
protected BufferedReader reader = null;
public PageLoader(String url) throws IOException {
parseURL(url);
}
protected void parseURL(String url) throws
MalformedURLException {
URL u = new URL(url);
host = u.getHost();
port = u.getPort();
if (port == -1) port = 80; // default
file = u.getFile();
}
Actual Code for HTTP Client
public void go() throws IOException {
try {
connect();
get();
} finally {
disconnect();
}
}
protected void connect() throws IOException {
socket = new Socket(host, port);
// create a writer on the socket
OutputStream out = socket.getOutputStream();
writer = new OutputStreamWriter(out, "latin1");
// create a reader on the socket
InputStream in = socket.getInputStream();
reader = new BufferedReader(new InputStreamReader(in,
"latin1"));
}
Actual Code for HTTP Client
protected void get() throws IOException {
// send the request
writer.write("GET " + file + " HTTP/1.0\r\n\n");
writer.flush();
// read and print the response
PrintWriter console = new PrintWriter(System.out);
String input;
while ((input = reader.readLine()) != null)
console.println(input);
console.flush();
}
protected void disconnect() throws IOException {
if (reader != null) reader.close();
if (writer != null) writer.close();
if (socket != null) socket.close();
}
Actual Code for HTTP Client
public static void main(String[] args) throws IOException {
Reader kbd = new FileReader(FileDescriptor.in);
BufferedReader bufferedKbd = new BufferedReader(kbd);
while (true) {
String url;
System.out.print("Please Enter URL: ");
System.out.flush();
if ((url = bufferedKbd.readLine()) == null) break;
try {
PageLoader loader = new PageLoader(url);
loader.go();
} catch (IOException e) {
e.printStackTrace();
continue;
}
System.out.println("- OK -");
}
System.out.println("- Bye -");
}
}
Simple TCP Connection in Java –
Stream Socket

In Java, TCP connection is made using Stream Socket
–
ServerSocket class create a server bound to a specific port



–
Constructor: ServerSocket(int port), throw IOException
accept() method listens for a connection request and accepts it,
the return value is the accepted client socket
close() method closes the server socket
Socket class create a steam socket and connects it to a
specific port at a specific IP address (server)




Constructor: Socket(String host, int port), throw IOException
getInputStream() returns an input stream from the other side of
the socket. May have IOException.
getOutputStream() returns an output stream to the other side of
the socket. May have IOException.
close() closes the socket
Steps in Establishing
Stream Sockets in Java




Network connection establishment requires to
import java.net.*
The server specifies that it is waiting for
connection at a particular port
A client attempts to connect to the server at the
port on the host (server)
If attempts succeeded, two sockets are created
–
Communication can be done through the data
input/output streams (java.io.* needed)
Stream Sockets on Server Side

Server specifies that it is waiting for connection using
ServerSocket class
–
Example: ServerSocket server = ServerSocket(5000);


Server declares its intention of accepting client connection by the
method accept
–
–

if port number cannot be used, IOException is thrown
Socket client = server.accept( );
When a client is successfully connected, the method returns a Socket
of client
getInputStream and getOutputStream methods of Socket establish
the communication channels with the client
–
–
DataInputStream in = new DataInputStream(client.getInputStream());
DataOutputStream out =
new DataOutputStream(client.getOutputStream());
Stream Sockets on Client Side

Two Socket constructor can be used to connect a
server
–
–
Socket(String hostname, int portNo)
Socket(InetAddress inetAdd, int portNo)



local available port is allocated arbitrarily, can be retrieved through
getLocalPort method of Socket
remote port (at server) can be obtained by getPort method of
Socket
As in the server side, getInputStream and
getOutputSteram are used to establish communication
channels
Sample Program on Client/Server
Echo Server
 Server declares listening
at a specific port
 Server blocks at accept
statement till connection
is established
 Server read byte from
the client and write it
back to the client until –1
(end-of-file) is read using
the I/O stream
Echo Client
 Client try to connect to the
server host at the specific port
 Socket created if server is
successfully connected
 Writer object is used to output
the message to the server
using the output data stream
 BufferedReader object is
used to read the bounce back
message from the server
using the input data stream
Addition Notes on Stream Socket


In the above example, server does use both the input
and output stream. You may have a server using only
input or output only (e.g. TimeServer in course
material)
There are other StreamSocket constructor that may be
useful:
–
–
ServerSocket(int port, int backlog)
The backlog parameter limits how many open connections are
allowed (used in multi-threaded server)
ServerSocket(int port, int backlog, InetAddress bindAddr)
The constructor is used for binding a server socket to a
specific IP of a multi-homed server (i.e. multiple IP addresses)
Multithreaded Server

In our previous example, the echo server handles one
connection at one time
–
–

It is okay when the interaction with client completes in a short time
It will block other connections and cause time-out if the connection
needs to maintain for a long time
Useful server has to be multithreaded in order to handle
multiple and simultaneous connections
–
–
–
Modified server will create a dedicated thread for each client every
time it accept a connection
All server operations are done in the thread instead of main
program – includes creating independent IO streams to each client
Each thread reads the respective data from each client and writes
to the screen
Client-Server Chat Application:
Server

Basic requirement of a chat server
–
–
–

It has to be multithreaded – multiple clients will be served
simultaneously
It has to keep track of all chat participants
When it receives a message from any participant, it has to
broadcast the message to all other participants
Flow of the server
–
–
–
Create a server socket to accept incoming connections
When a connection arrives, create a new thread to handle the
connection. The handlers has to be stored in a place that all
threads can access (for broadcasting)
In the handler thread, wait for incoming messages. Broadcast
the message to all other handlers when an incoming message
is received
Chat Server

The code is very similar to the server in the previous example
import java.net.*;
import java.io.*;
public class ChatServer {
public static void main(String args[]) throws IOException {
if (args.length != 1)
throw new IllegalArgumentException(
"Syntax: ChatServer <port>");
int port = Integer.parseInt(args[0]);
ServerSocket server = new ServerSocket(port);
// listen for connections
while (true) {
Socket client = server.accept();
System.out.println("New client from " +
client.getInetAddress());
// spawn new handler
ChatHandler handler = new ChatHandler(client);
handler.start();
}
}
}
Chat Handler in Server


Each handler thread interact with one client
A static vector stores all running chat handlers
–
–
–

We use DataInputStream and DataOutputStream to
read/write the message
–

Handler is added to the vector when start() method is called
Handler is removed from the vector when stop() is called
Message is broadcasted to all handlers in the vector
readUTF() / writeUTF() enables us to read/write multi-lingual
text
Any method that needs to access the static variable
needs to be synchronized
Source Code: Chat Handler
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatHandler implements Runnable {
// the vector of all handlers
protected static Vector handlers = new Vector();
protected Socket socket;
protected DataInputStream dataIn;
protected DataOutputStream dataOut;
protected Thread listener;
public ChatHandler(Socket socket) {
this.socket = socket;
}
Source Code: Chat Handler
public synchronized void start() {
if (listener == null) {
try {
dataIn = new DataInputStream(
new BufferedInputStream(socket.getInputStream()));
dataOut = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));
listener = new Thread(this);
listener.start();
} catch (IOException ignored) { }
}
}
public synchronized void stop() {
if (listener != null) {
try {
if (listener != Thread.currentThread())
listener.interrupt();
listener = null;
dataOut.close();
} catch (IOException ignored) { }
}
}
Source Code: Chat Handler
public void run() {
try {
// add us to the pool of handlers
handlers.addElement(this);
while (!Thread.interrupted()) {
// read a message and broadcast it
String message = dataIn.readUTF();
broadcast(message);
}
} catch (EOFException ignored) {
} catch (IOException ex) {
if (listener == Thread.currentThread())
ex.printStackTrace();
} finally {
// thread is to exit, so remove us from the handler
handlers.removeElement(this);
}
stop();
}
Source Code: Chat Handler
protected void broadcast(String message) {
synchronized (handlers) {
Enumeration enum = handlers.elements();
while (enum.hasMoreElements()) {
ChatHandler handler = (ChatHandler) enum.nextElement();
try {
handler.dataOut.writeUTF(message);
handler.dataOut.flush();
} catch (IOException ex) {
// the connection may have dropped
handler.stop();
}
}
}
}
}
Client-Server Chat Application:
Client

The client contains a simple user interface with
an output area and an input box
–

When user hits <Return> on the input box, we send
the content of the input box to the server
A thread is created to receive the data from the
the server
–
The main thread is used to handle the Client’s UI
Source Code: Chat Client
import
import
import
import
java.io.*;
java.net.*;
java.awt.*;
java.awt.event.*;
public class ChatClient implements Runnable, WindowListener,
ActionListener {
protected String host;
protected int port;
protected String username;
protected Frame frame;
protected TextArea output;
protected TextField input;
protected DataInputStream dataIn;
protected DataOutputStream dataOut;
protected Thread listener;
public ChatClient(String host, int port, String username) {
this.host = host;
this.port = port;
this.username = username;
}
Source Code: Chat Client
public synchronized void start() throws IOException {
if (listener == null) {
Socket socket = new Socket(host, port);
try {
dataIn = new DataInputStream(
new BufferedInputStream(
socket.getInputStream()));
dataOut = new DataOutputStream(
new BufferedOutputStream(
socket.getOutputStream()));
} catch (IOException ex) {
socket.close();
throw ex;
}
listener = new Thread(this);
listener.start();
makeChatUI();
}
}
Source Code: Chat Client
public synchronized void stop() throws IOException {
frame.setVisible(false);
if (listener != null) {
listener.interrupt();
listener = null;
dataOut.close();
}
}
public void run() {
try {
while (!Thread.interrupted()) {
String line = dataIn.readUTF();
output.append(line + "\n");
}
} catch (IOException ex) {
handleIOException(ex);
}
}
Source Code: Chat Client
public synchronized void stop() throws IOException {
frame.setVisible(false);
if (listener != null) {
listener.interrupt();
listener = null;
dataOut.close();
}
}
public void run() {
try {
while (!Thread.interrupted()) {
String line = dataIn.readUTF();
output.append(line + "\n");
}
} catch (IOException ex) {
handleIOException(ex);
}
}
Source
Code:
Chat
Client
protected synchronized void handleIOException(IOException ex) {
if (listener != null) {
output.append(ex + "\n");
input.setVisible(false);
frame.validate();
if (listener != Thread.currentThread())
listener.interrupt();
listener = null;
try { dataOut.close();
} catch (IOException ignored) { }
}
}
protected void makeChatUI() {
frame = new Frame(
"ChatClient [" + host + ':' + port + "]" +
" (" + username + ")");
frame.addWindowListener(this);
output = new TextArea();
output.setEditable(false);
input = new TextField();
input.addActionListener(this);
frame.add("Center", output); frame.add("South", input);
frame.pack(); frame.setVisible(true);
}
Source Code: Chat Client
public void windowOpened(WindowEvent event) {
input.requestFocus();
}
public void windowClosing(WindowEvent event) {
try {
stop();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void actionPerformed(ActionEvent event) {
try {
input.selectAll();
dataOut.writeUTF(username+": "+event.getActionCommand());
dataOut.flush();
} catch (IOException ex) {
handleIOException(ex);
}
}
Source Code: Chat Client
public
public
public
public
public
void
void
void
void
void
windowClosed(WindowEvent event) {}
windowIconified(WindowEvent event) {}
windowDeiconified(WindowEvent event) {}
windowActivated(WindowEvent event) {}
windowDeactivated(WindowEvent event) {}
public static void main(String[] args) throws IOException {
if ((args.length != 2) || (args[0].indexOf(':') < 0))
throw new IllegalArgumentException(
"Syntax: ChatClient <host>:<port> <username>");
int idx = args[0].indexOf(':');
String host = args[0].substring(0, idx);
String username = args[1];
int port = Integer.parseInt(args[0].substring(idx + 1));
ChatClient client = new ChatClient(host, port, username);
client.start();
}
}
Structure of UDP Server and Client

UDP Server
–
–
–
–

Create a datagram packet to hold the incoming packet
Create a daragram socket
Use the socket to receive a packet
Close the socket
UDP Client
–
–
–
–
Prepare the packet by specifying the destination address, port
and data
Create a datagram socket
Use the socket to send the packet
Close the socket
UDP Connection in Java –
Datagram Socket

java.net.DatagramSocket is used to implement
datagram socket in Java
–
–


Server needs to use the constructor with port number,
so that clients can know the port to contact the server
Client can use both constructors
–

DatagramSocket(int portNo)
DatagramSocket( )
Server can always get the port number and IP address from
the client’s datagram
Possible Exception
–
–
SocketException – if the port has been used by another server
SecurityException – if the security manager does not allow the
connection
UDP Connection in Java –
Datagram Packet


Datagram packets (java.net.DatagramPacket) are used
to package the data we want to send.
DatagramPacket(byte[] buf, int length, InetAdress
address, int port)
–
–
–
–

Constructor used to send message
buf = message content
length = message length (per packet)
address and port = destination of the message
DatagramPacket(byte[] buf, int length)
–
–
Constructor to be used to receive other’s message
Address and port number can be retrieved from the received
packet
Datagram Socket and Packet
Methods

DatagramSocket provides methods to receive and
send a packet
–
–

void receive(DatagramPacket data)
void send (DatagramPacket data)
DatagramPacket provides methods to set and inquire
about the status of the packet. For example,
–
–
–
int getPort( ) / void setPort(int port)
InetAddress getAddress( ) / void setAddress(InetAddress
address)
int getLength( ) / void setLength(int length)
Datagram Packet Length and
Exceptions

Datagram packet length has different meaning from
time to time
–
–
–

Before a packet is sent, the length field represents the size of
buffer
After returning from receive method, the length field represents
the size received of packet
Thus, it is important to reset the length of the packet if the
same packet is used each time
Possible exceptions of DatagramPacket
–
–
–
IllegalArgumentException – when the packet length is shorter
than the length of message contents
IOException – if there is transmission error
SecurityException – if the caller does not have the access to
the method
Server Side Datagram Socket




Server specifies it is listening at a particular port (in
constructor)
Empty DatagramPacket is created as buffer for
incoming datagram
Wait for message by invoking receive method
After a message is received
–

if reply message is to be send, get the IP address and port
number from the received datagram packet and message can
be sent accordingly
Multiple client can be supported without multithreading
–
No connection is created, thus server can receive any
datagrams from any host
Sample code: UDPEchoServer
import java.net.*;
import java.io.*;
public class UDPEchoServer {
protected int port;
public UDPEchoServer(int port) {
this.port = port;
}
public void go() throws IOException {
DatagramSocket socket = new DatagramSocket(port);
while (true) {
System.out.println("Waiting to receive packets");
// receive a packet
byte buffer[] = new byte[65508];
DatagramPacket packet =
new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
// echo the packet back to the sender
System.out.print("* A packet is rcvd and echoed back to:");
System.out.println(packet.getAddress()+":"+
packet.getPort());
socket.send(packet);
}
}
Sample code: UDPEchoServer
(cont’d)
public static void main(String[] args) throws
IOException {
if (args.length != 1)
throw new IllegalArgumentException
("Syntax: UDPEchoServer <port>");
UDPEchoServer server = new
UDPEchoServer(Integer.parseInt(args[0]));
server.go();
}
}
Client Side Datagram Socket





Create a datagram socket
Create a datagram packet with destination IP and port
number
Use send method to send message
Create new empty packet and call receive method to
wait for reply messages if necessary
In a two-way communication, when there are both
reading and writing, multithreads will be needed to
handle read and write process separately
Sample code: UDPEchoClient
import java.net.*;
import java.io.*;
public class UDPEchoClient {
protected DatagramSocket socket;
protected DatagramPacket packet;
public void go(String host, int port, String message)
throws IOException {
socket = new DatagramSocket();
buildPacket(message, host, port);
socket.send(packet);
receivePacket();
socket.close();
}
Sample code: UDPEchoClient
protected void buildPacket(String message,String host,int port)
throws IOException {
ByteArrayOutputStream byteArrayOut =
new ByteArrayOutputStream();
DataOutputStream dataOut =
new DataOutputStream(byteArrayOut);
dataOut.writeUTF(message);
byte[] data = byteArrayOut.toByteArray();
packet = new DatagramPacket(data, data.length,
InetAddress.getByName(host), port);
}
protected void receivePacket() throws IOException {
byte buffer[] = new byte[65508];
DatagramPacket packet =
new DatagramPacket(buffer, buffer.length);
socket.receive(packet);
ByteArrayInputStream byteArrayIn = new
ByteArrayInputStream(packet.getData(),0,packet.getLength());
DataInputStream dataIn = new DataInputStream(byteArrayIn);
String result = dataIn.readUTF();
System.out.println("Received: " + result + ".");
}
Sample code: UDPEchoClient
public static void main(String[] args) throws IOException {
if (args.length != 3)
throw new IllegalArgumentException
("Syntax: UDPEchoClient <host> <port> <msg>");
UDPEchoClient client = new UDPEchoClient();
client.go(
args[0], Integer.parseInt(args[1]), args[2] );
}
}