Title: Web Programming Course
1Web Programming Course
- Lecture 7 Distributed Programming 2
2Network API
- The services provided by the operating system
that provide the interface between application
and protocol software. - i.e., between application and protocol layers
Application
Network API
Protocol A
Protocol B
Protocol C
3Example and Motivation
- Data sent across the Internet using is split to
packets. - Packets range in size from a few Bytes to about
60KB. - Different types of hosts can receive it.
- Rationale
- If a packet is lost, it should be retransmitted
independently of all other packets. - If packets arrive out of order they should be
reordered. - However these details are transparent to the
developer. - Native network API transparently handles the
splitting and the reassembly of data,
retransmissions and adaptation to the appropriate
host, etc
4Network API
- Generic Programming Interface
- Support for message-oriented and
connection-oriented communication. - Support multiple communication protocols.
- Host and platform independence.
-
- Protocols do not include the API definition.
- Socket is one of such APIs
5Socket
- A socket is an abstract representation of a
communication endpoint. - Sockets work similarly to streams.
- Sockets have special needs
- Specify local and remote communication endpoints
- Initiate a connection and wait for incoming
connections - Send and receive data
- Terminate a connection gracefully
- Error handling
6Socket Example
- A server runs on a specific computer and has a
socket that is bound to a specific port number. - A client makes a connection request based on the
host name of the server and the port number.
7Socket Example
- Upon acceptance, the server gets a new socket
bound to a different port. - If the connection is accepted, and a socket is
opened, the client uses the socket to
communicate the server. - The server continued listening to the original
socket for new requests while serving the
connected client.
8Socket Descriptor
- OS maintains a set of Socket Descriptors for each
process - Socket Descriptor Table
- Socket Data Structure
- Address Data Structure
Similar to File Descriptors Table
9Transmission Control Protocol (TCP) An Analogy
- TCP
- Reliable guarantee delivery
- Byte stream in-order delivery
- Connection-oriented single socket per
connection - Setup connection followed by data transfer
- Telephone Call
- Guaranteed delivery
- In-order delivery
- Connection-oriented
- Setup connection followed by conversation
Example TCP Applications Web, Email, Telnet
10The java.net.Socket class
- To connect to a host, you must create a new
Socket object. - public Socket(String host, int port) throws
UnknownHostException, IOException - public Socket(InetAddress address, int port)
throws IOException - public Socket(String host, int port, InetAddress
localAddress, int localPort) throws
IOException - public Socket(InetAddress address, int port,
InetAddress localAddress, int localPort) throws
IOException - public InputStream getInputStream() throws
IOException - public OutputStream getOutputStream() throws
IOException - public synchronized void close() throws
IOException
11Constructing Socket Objects
- To build a socket, the remote host and the port
should be specified - The host may be specified as either a string or
as an InetAddress object. - The port should be an int between 1 and 65535.
- try
- Socket s new Socket(www.haifa.ac.il", 80)
-
- catch (UnknownHostException e) e.printStackTrace(
)
12Constructing Socket Objects
- The constructor attempts to connect the
underlying socket to the specified host. - If the connection can not be established (for any
reason), an IOException is thrown. - The constructor can be used to determine the port
that the host is listening.
13Port Scanner
- String host "www.haifa.ac.il"
- for (int port 1 port lt 65536 port)
- try
- Socket s new Socket(host, port)
- System.out.println( "There is a server on
port port " of " host) - s.close()
-
- catch (UnknownHostException e)
- System.err.println(e)
- break
-
- catch (IOException e)
- System.out.println( "No server on port
port " of " host) -
14The java.net.Socket class
- There are methods to return information about the
socket - public InetAddress getInetAddress()
- public InetAddress getLocalAddress()
- public int getPort()
- public int getLocalPort()
- public String toString()
15Local Port and Remote Port
- Remote port is usually a well-known port
- The client also uses a port chosen by the system
at run-time from the available unused ports. - try
- Socket theSocket new Socket(host, 80)
- System.out.println("Connected to "
theSocket.getInetAddress() " on port "
theSocket.getPort() " from port "
theSocket.getLocalPort() " of "
theSocket.getLocalAddress()) -
- catch (UnknownHostException e)
- System.err.println("I can't find "
host) -
16Reading Input from a Socket
- Once a socket has connected to the server
- The data is sent to the server via an output
stream. - The data received from the server via an input
stream. - try
- Socket s new Socket(host, 13)
- InputStream is s.getInputStream()
- InputStreamReader isr new
InputStreamReader(is) - BufferedReader br new BufferedReader(isr)
- String theTime br.readLine()
- System.out.println(theTime)
-
- catch (IOException e)
17Writing Output to a Socket
- try
- Socket theSocket new Socket(host, 7)
- BufferedReader networkIn new
BufferedReader( - new InputStreamReader(theSocket.getInputSt
ream())) - BufferedReader userIn new BufferedReader(
- new InputStreamReader(System.in))
- PrintWriter out new PrintWriter
(theSocket.getOutputStream()) - while (true)
- String theLine userIn.readLine()
- if (theLine.equals(".")) break
- out.println(theLine)
- out.flush()
- System.out.println(networkIn.readLine())
-
-
- catch (IOException e) System.err.println(e)
18Finger Protocol
- Finger is a utility that gives information about
the accounts being managed by a server. - It is running on port 79.
- When login or name are sent
- It returns the details of the users with such
name/login - When no parameters are sent
- It returns the details of all currently logged
users
19Finger Client
- try
- Socket connection new Socket(hostname,
DEFAULT_PORT) - Writer out new OutputStreamWriter(
- connection.getOutputStream())
- out.write("john")
- out.write("\r\n")
- out.flush()
- InputStream is connection.getInputStream()
- BufferedInputStream buffer new
BufferedInputStream(is) - InputStreamReader in new
InputStreamReader(buffer) - int c
- while ((c in.read()) ! -1)
- System.out.write(c)
- catch (IOException e) System.err.println(e)
20Sockets and Concurrency
- Java places no restrictions on concurrent reading
and writing to/from sockets. - One thread can read from a socket while another
thread writes to the socket. - Preventing this requires synchronization.
- Use wait(), notify(),
21Server Sockets
- There are two ends to each connection
- Client initiating the connection (active)
- Server responding to the connection (passive)
- The server side waits for the clients to connect
to it. - A server socket binds to a particular port on the
server host. As it is successfully bound to a
port, it - Listens for incoming connection attempts.
- Upon detecting a connection attempt, it is
accepted. - This creates a socket between the client and the
server over which they will communicate.
22Server Sockets
- Multiple clients can connect to the same port on
the server at the same time. - Transferred data is distinguished by the port to
which it is addressed, and the client host and
port from which it came. - Since a server may need to handle many
connections in parallel, server programs tend to
be multi-threaded.
23Server Sockets
- Usually the server socket listening on the port
will only accept the connections and will pass
the actual processing of connections to a
separate thread. - Incoming connections are stored in a queue until
the server can accept them. - Once the queue fills up further incoming
connections are refused until space in the queue
opens up.
24The java.net.ServerSocket Class
- public ServerSocket(int port) throws
IOException - public ServerSocket(int port, int backlog)
throws IOException - public ServerSocket(int port, int backlog,
InetAddress bindAddr) throws IOException - public Socket accept() throws IOException
- public void close() throws IOException
- public InetAddress getInetAddress()
- public int getLocalPort()
25Constructing ServerSocket Object
- When ServerSocket object is created, it attempts
to bind to the port given by the port argument. - try
- ServerSocket ss new ServerSocket(80)
-
- catch (IOException e)
- System.err.println(e)
-
- If another server socket is already listening to
the port, a java.net.BindException, is thrown.
26Port 0
- Port 0 tells Java to pick automatically one of
the available ports. - The port that was picked can be determined with
the getLocalPort() method. - try
- ServerSocket appSocket new
ServerSocket(0) - int port appSocket.getLocalPort()
-
- catch (IOException e)
- System.err.println(e)
27Establishing Connection with Clients
- accept() method blocks until a client request for
a connection is received. - It returns a Socket object when the connection
with the client is established. - try
- ServerSocket ss new ServerSocket(2345)
- Socket s ss.accept()
-
- catch (IOException e)
- System.err.println(e)
-
28Reading Data from a Client
- try
- ServerSocket ss new ServerSocket(2345)
- Socket s ss.accept()
- BufferedReader in new BufferedReader( new
InputStreamReader(s.getInputStream())) - String input in.readLine()
-
- catch (IOException e)
- System.err.println(e)
29Writing Data to a Client
- try
- ServerSocket ss new ServerSocket(2345)
- Socket s ss.accept()
- PrintWriter pw new PrintWriter(s.getOutput
Stream()) - pw.println("Hello There!")
- pw.println("Goodbye now.)
- s.close()
-
- catch (IOException e)
- System.err.println(e)
-
30Example Hello Server
- Client connects to the server
- Server sends connected to the client.
- Client sends a message
- Server check the message
- If it is hi, then hello message is sent to
the client. - If it is bye, then closing session message is
sent, and the connection is closed. - If it is any other message, the server echoes the
message back with the current date and time. - Operations 3 and 4 continue until the client send
bye message.
31Example Hello Server
- import java.net.
- import java.io.
- public class HelloServer
- public static void main(String args) throws
IOException - ServerSocket serverSocket null
- try
- serverSocket new ServerSocket(2000)
-
- catch (IOException e)
- System.err.println("Can't listen to 2000")
-
32Example Hello Server
- Socket clientSocket null
- try
- clientSocket serverSocket.accept()
-
- catch (IOException e)
- System.err.println("Accept failed.")
-
- PrintWriter out new PrintWriter(clientSo
cket.getOutputStream(),true) - BufferedReader in new BufferedReader(new
InputStreamReader(clientSocket.getInputStream()))
- String input
33Example Hello Server
- out.println("Connected!")
- while ((input in.readLine()) ! null)
- if(input.equalsIgnoreCase("Hi"))
- out.println("Hello")
- else if(input.equalsIgnoreCase("Bye"))
- out.println("Closing session!")
- break
-
- else out.println(new Date()"" input)
-
- out.close() in.close()
- clientSocket.close() serverSocket.close()
-
34Example Hello Client
- import java.io.
- import java.net.
- public class HelloClient
- public static void main(String args) throws
IOException - Socket helloSocket null
- PrintWriter out null
- BufferedReader in null
- try
- helloSocket new Socket("127.0.0.1", 2000)
- out new PrintWriter(
helloSocket.getOutputStream(), true) - in new BufferedReader(new
InputStreamReader(helloSocket.getInputStream())) -
35Example Hello Client
- catch (UnknownHostException e)
- System.err.println("Unknown host.")
- System.exit(1)
-
- catch (IOException e)
- System.err.println("Couldn't get I/O for
the host.") - System.exit(1)
-
- BufferedReader stdIn new BufferedReader(new
InputStreamReader(System.in)) - String server
- String user ""
36Example Hello Client
- while ((server in.readLine()) ! null)
- System.out.println("Server " server)
- user stdIn.readLine()
- if (user.equalsIgnoreCase("Bye")) break
- if (user ! null)
- System.out.println("Client " user)
- out.println(user)
-
-
- out.close() in.close()
- stdIn.close() helloSocket.close()
-
37Running Client-Server Application
- Run Server
- java HelloServer
- Run Client in another command window
- java HelloClient
- Server Connected!
- hi
- Client hi
- Server Hello
- message
- Client message
- Server Sat Dec 01 100113 IST 2005message
- bye
- Client bye
- Server Closing session!
38TCP Sockets
Server (running on Host A)
Client (running on Host B)
39Few Remarks on Hello protocol
- What happens if clients try to access the server
while the server is still connected to another
client ? - They are blocked. Even if the client is not using
the connection anymore! - When the server disconnect from the client he is
currently serving, it closes server socket and
shuts down. - The new clients can not get the service.
40Few Remarks on Hello protocol
- Partial solution the server will continue to
serve the clients each in turn - while (true)
- try
- clientSocket serverSocket.accept()
- PrintWriter out new
PrintWriter(clientSocket.getOutputStream(),
true) - BufferedReader in new BufferedReader(
- new InputStreamReader(
clientSocket.getInputStream())) -
-
- Better solution use separate thread to serve
each client.
41Example Power Server
- try
- ServerSocket serverSocket new
ServerSocket(3000) -
- catch (IOException e)
- System.err.println("Could not listen on port
3000.") -
- while (true)
- try
- Socket clientSocket serverSocket.accept()
- DataOutputStream out new
DataOutputStream(clientSocket.getOutputStream()) - DataInputStream in new
DataInputStream(clientSocket.getInputStream()) -
- catch (IOException e)
- System.err.println("Accept failed.")
-
42Example Power Server
- int var10, var20
- var1 in.readInt()
- var2 in.readInt()
- if(var10)
- out.writeLong(0)
- else if (var20)
- out.writeLong(1)
- else
- long result (long)Math.pow(var1,var2)
- out.writeLong(result)
-
- out.close() in.close() clientSocket.close()
-
- serverSocket.close()
-
43Example Power Client
- try
- socket new Socket("127.0.0.1", 3000)
- DataOutputStream out new DataOutputStream(soc
ket.getOutputStream()) - DataInputStream in new DataInputStream(socke
t.getInputStream()) - out.writeInt(var1)
- out.writeInt(var2)
- long tmp in.readLong()
- out.close()
- in.close()
- socket.close()
-
- catch (Exception e) e.printStackTrace()
44Example Multi-Threaded Server
- import java.net.
- import java.io.
- public class ThreadedEchoServer extends Thread
- public final static int defaultPort 2345
- Socket theConnection
- public static void main(String args)
- int port defaultPort
- try
- port Integer.parseInt(args0)
-
- catch (Exception e) e.printStackTrace()
- if (port lt 0 port gt 65536) port
defaultPort
45Example Multi-Threaded Server
- try
- ServerSocket ss new ServerSocket(port)
- while (true)
- try
- Socket s ss.accept()
- ThreadedEchoServer tes new
ThreadedEchoServer(s) - tes.start()
-
- catch (IOException e) e.printStackTrace()
-
- catch (IOException e) e.printStackTrace()
-
46Example Multi-Threaded Server
- public ThreadedEchoServer(Socket s)
- theConnection s
-
- public void run()
- try
- OutputStream os theConnection.getOutputStr
eam() - InputStream is theConnection.getInputStrea
m() - while (true)
- int n is.read()
- if (n -1) break
- os.write(n)
- os.flush()
-
-
- catch (IOException e)
-
47Example Multi-Threaded Server
- main() is using the same reference (tes) to
instantiate each thread - If the main thread would like to manage the
threads, it can define a data structure of
threads and add each new thread to this data
structure. - The client for multi-threaded server is a regular
EchoServer Client. - In fact, the client does not know whether the
server is a single threaded or multi-threaded.
48Adding a Thread Pool to a Server
- Spawning a new thread for each connection takes a
non-trivial amount of time, especially on a
heavily loaded server. - An alternative approach
- to create a pool of threads when the server
launches - to store incoming connections in a queue,
- to have threads in the pool progressively
removing the connections from the queue and
processing them. - This is particularly simple since the OS really
stores the incoming connections in a queue.
49Adding a Thread Pool to a Server
- import java.net.
- import java.io.
- public class PoolEchoServer extends Thread
- public final static int defaultPort 2345
- ServerSocket theServer
- static int numberOfThreads 10
- public static void main(String args)
- int port defaultPort
- try
- port Integer.parseInt(args0)
- catch (Exception e) e.printStackTrace()
- if (port lt 0 port gt 65536)
- port defaultPort
50Adding a Thread Pool to a Server
- try
- ServerSocket ss new ServerSocket(port)
- for (int i 0 i lt numberOfThreads i)
- PoolEchoServer pes new
PoolEchoServer(ss) - pes.start()
-
-
- catch (IOException e) e.printStackTrace()
-
-
- public PoolEchoServer(ServerSocket ss)
- theServer ss
-
51Adding a Thread Pool to a Server
- public void run()
- while (true)
- try
- Socket s theServer.accept()
- OutputStream out s.getOutputStream()
- InputStream in s.getInputStream()
- while (true)
- int n in.read()
- if (n -1) break
- out.write(n) out.flush()
- // end while
- // end try
- catch (IOException e) e.printStackTrace()
- // end while
- // end run
52Synchronization Problem
- If the threads are sharing a resource, they may
have to synchronize access to the shared
resource. - Example
- The server manages a log file in which each
client details are written. - Each thread may use a shared stream object.
- Assume it is a static member of the server thread
class - static Writer log new FileWriter(log.txt)
- Synchronize it on the server class object
53Introducing UDP
- The User Datagram Protocol (UDP), provides
unguaranteed, connectionless transmission of data
across an IP network. - TCP, provides reliable, connection-oriented
transmission of data. - Both TCP and UDP split data into packets called
datagrams. - TCP includes extra headers in the datagram to
enable retransmission of lost packets and
reassembly of packets if they arrive out of
order.
54Introducing UDP
- UDP does not provide this.
- If a UDP packet is lost, it will not be
retransmitted. - Packets appear in the receiving host not
necessarily in the order they were sent. - As a result, UDP can be up to 3 times faster than
TCP - There are many applications for which reliable
transmission of data is not nearly as important
as speed. - In these cases, UDP is useful.
55User Datagram Protocol (UDP) An Analogy
- UDP
- Single socket to receive messages
- No guarantee of delivery
- Not necessarily in-order delivery
- Datagram independent packets
- Must address each packet
- Postal Mail
- Single mailbox to receive letters
- Unreliable
- Not necessarily in-order delivery
- Letters sent independently
- Must address each reply
- Postal Mail
- Single mailbox to receive messages
- Unreliable ?
- Not necessarily in-order delivery
- Each letter is independent
- Must address each reply
Example UDP applications Multimedia, Voice over
IP
56The java.net.DatagramSocket Class
- Is used to send and receive DatagramPacket
objects. - Since UDP is connectionless, streams are not used
and the data must be split into packets of less
than 60KB. - The DatagramSocket class is a connection to a
port that does the sending and receiving. - There is no distinction between a UDP socket and
a UDP server socket. - DatagramSocket can send to multiple, different
addresses. - Unlike in TCP, the target address is stored in
the packet, and not in the socket.
57The java.net.DatagramSocket Class
- public DatagramSocket() throws SocketException
- public DatagramSocket(int port) throws
SocketException - public DatagramSocket(int port, InetAddress
laddr) throws SocketException - The first constructor is used for datagram
sockets that are intended to act as clients - They will send datagrams before receiving any.
- The other 2 constructors specify the port and
(optionally) the IP address of the socket, are
intended for servers - They must run on a well-known port.
58The java.net.DatagramPacket Class
- A wrapper for an array of bytes from which data
is sent or into which data is received. - It also contains the address and port to which
the packet will be sent. - public DatagramPacket(byte data, int length)
- public DatagramPacket(byte data, int length,
InetAddress host, int port) - The byte array is stored by reference, not by
value. - If changed, the DatagramPacket object changes as
well.
59The java.net.DatagramPacket Class
- try
- InetAddress ia new InetAddess("www.haifa.ac.
il") - int port 2345
- String s "My UDP Packet"
- byte b s.getBytes()
- DatagramPacket dp new DatagramPacket(b,
b.length, ia, port) -
- catch (UnknownHostException e)
- e.printStackTrace()
60The java.net.DatagramPacket Class
- public synchronized void setAddress(InetAddress
host) - public synchronized void setPort(int port)
- public synchronized void setData(byte
buffer) - public synchronized void setLength(int length)
- public synchronized InetAddress getAddress()
- public synchronized int getPort()
- public synchronized byte getData()
- public synchronized int getLength()
61Datagram Example
- String s "This is a test."
- byte data s.getBytes()
- try
- InetAddress ia InetAddress.getByName("www.h
aifa.ac.il") - int port 2345
- DatagramPacket dp new DatagramPacket(data,
data.length, ia, port) - System.out.println("The packet is addressed to
dp.getAddress() " on port "
dp.getPort()) - System.out.println("There are "
dp.getLength() " bytes of data in the
packet") -
- catch(Exception e) e.printStackTrace()
62Sending UDP Datagrams
- try
- InetAddress ia new InetAddess("www.haifa.ac.il
") - int port 2345
- String s "My UDP Packet"
- byte b s.getBytes()
- DatagramPacket dp new DatagramPacket(b,
b.length, ia , port) -
- catch (UnknownHostException e) e.printStackTrace(
) - try
- DatagramSocket sender new DatagramSocket()
- sender.send(dp)
-
- catch (IOException e) e.printStackTrace()
63Receiving UDP Datagrams
- public synchronized void receive (DatagramPacket
dp) throws IOException - The calling thread blocks until receiving a
datagram. - The buffer of the DatagramPacket contains the
data received from the datagram. - getPort() and and getAddress() determines where
the packet came from, getData() retrieves the
data, and getLength() returns the size of the
data in bytes. - If the received packet is too long for the
buffer, it is truncated to the length of the
buffer.
64Receiving UDP Datagrams
- try
- byte buffer new byte65536 //max. packet
size - DatagramPacket incoming new
DatagramPacket(buffer, buffer.length) - DatagramSocket ds new DatagramSocket(2134)
- ds.receive(dp)
- byte data dp.getData()
- String s new String(data, 0,
data.getLength()) - System.out.println("Port " dp.getPort() "
on " dp.getAddress() " sent " s) -
- catch (IOException e)
- e.printStackTrace()
65Sending and Receiving Datagrams
- import java.net.
- import java.io.
- public class UDPEchoClient extends Thread
- public final static int port 7
- DatagramSocket ds
- public static void main(String args)
- InputStreamReader isr new
InputStreamReader(System.in) - BufferedReader br new BufferedReader(isr)
- String theLine
- DatagramSocket ds null
- InetAddress server null
- try
- server InetAddress.getByName("www.haifa.ac
.il") - ds new DatagramSocket()
-
- catch (IOException e)
- System.err.println(e)
- System.exit(1)
-
66Sending and Receiving Datagrams
- UDPEchoClient uec new UDPEchoClient(ds)uec.st
art() - try
- while ((theLine br.readLine()) ! null)
- byte data theLine.getBytes()
- DatagramPacket dp new
DatagramPacket(data, data.length, server, port) - ds.send(dp)
- Thread.yield()
-
-
- catch (IOException e) e.printStackTrace()
uec.stop() -
- public UDPEchoClient(DatagramSocket ds)
this.ds ds
67Sending and Receiving Datagrams
- public void run()
- byte buffer new byte1024
- DatagramPacket response new
DatagramPacket(buffer, buffer.length) - while (true)
- try
- response.setLength(buffer.length)
- ds.receive(response)
- byte data response.getData()
- System.out.println(new String(data, 0,
response.getLength())) -
- catch (IOException e) System.err.println(e)
-
-
-
68UDP Sockets
Server (running on Host A)
Client (running on Host B)
create socket,
clientSocket DatagramSocket(A, x)
Create, address (hostid, portx, send datagram
request using clientSocket
69Example Capitalizer UDP Server
import java.io. import java.net. class
UDPServer public static void main(String
args) throws Exception DatagramSocket
serverSocket new DatagramSocket(9876)
byte receiveData new byte1024
byte sendData new byte1024
while(true) DatagramPacket
receivePacket new
DatagramPacket(receiveData,
receiveData.length)
serverSocket.receive(receivePacket)
70Example Capitalizer UDP Server
String sentence new String(receivePacke
t.getData()) InetAddress ipa
receivePacket.getAddress() int port
receivePacket.getPort() String
capitalizedSentence sentence.toUpperCase()
sendData capitalizedSentence.getBytes()
DatagramPacket sendPacket
new DatagramPacket(sendData, sendData.length,
ipa, port) serverSocket.send(sendPacke
t)
71Example Capitalizer UDP Client
import java.io. import java.net. class
UDPClient public static void main(String
args) throws Exception
BufferedReader inFromUser new
BufferedReader(new InputStreamReader(System.in
)) DatagramSocket clientSocket new
DatagramSocket() InetAddress IPAddress
InetAddress.getByName("hostname")
byte sendData new byte1024 byte
receiveData new byte1024 String
sentence inFromUser.readLine() sendData
sentence.getBytes()
72Example Capitalizer UDP Client
DatagramPacket sendPacket new
DatagramPacket(sendData, sendData.length,
IPAddress, 9876) clientSocket.send(sendPac
ket) DatagramPacket receivePacket
new DatagramPacket(receiveData,
receiveData.length) clientSocket.receive(r
eceivePacket) String modifiedSentence
new String(receivePacket.getData())
System.out.println("FROM SERVER"
modifiedSentence) clientSocket.close()