Lecture note 4

Download Report

Transcript Lecture note 4

COMPS311F
Li Tak Sing
Case study: consumers and
producers
 A fixed size buffer which can hold at most certain integers.
 A number of producers which generate integers randomly at
random intervals. The integers will then be put into the
buffer.
 A number of consumers which get integers from the buffer
at random intervals.
File location
 The application can be accessed at:
 http://plbpc001.ouhk.edu.hk/~mt311f/examples/mt311201
0/build/classes/CP.html
 The source file can be obtained at:
 http://plbpc001.ouhk.edu.hk/~mt311f/examples/mt311201
0/src/CP.java
Colour coding
 black: The thread is trying to lock the buffer
 blue: The thread has release the lock because it cannot
process.
 green: The thread is sleeping.
 red: The thread has finished the current task.
 orange: The thread has acquired the lock of the buffer.
Attributes
 private int size = 3;
 private Producer[] p;
 private Consumer[] c;
 private javax.swing.JButton stack[] = new
javax.swing.JButton[size];
 private int no = 0;
The put method
private synchronized void put(int i, Producer p) {
p.setStatus("locking " + i);
try {Thread.sleep(1000);} catch (Exception e) {};
while (no == size) {
try {
p.setStatus("waiting to put " + i);
wait();
} catch (Exception e) {
}
}
notifyAll();
stack[size-(++no)].setText(Integer.toString(i));
p.setStatus("put "+i);
try {Thread.sleep(1000);} catch (Exception e) {};
}
The get method
private synchronized int get(Consumer p) {
p.setStatus("locking");
try {Thread.sleep(1000);} catch (Exception e) {};
while (no == 0) {
try {
p.setStatus("waiting to get ");
wait();
} catch (Exception e) {
}
}
notifyAll();
The get method
int i = 0;
try {
i = Integer.parseInt(stack[size-(no)].getText());
stack[size-no].setText("");
no--;
} catch (Exception e) {
}
notifyAll();
p.setStatus("got "+i);
try {Thread.sleep(1000);} catch (Exception e) {};
return i;
}
CPButton
 This is the class of both Producer and Consumer.
 It is a JButton and has implemented the Runnable interface.
Producer
public void run() {
while (true) {
try {
int number = (int) (Math.random() * 10);
setStatus("putting "+number);
put(number,this);
int interval = ((int) (Math.random() * 10000));
this.setStatus("sleeping "+(interval/1000)+"secs");
Thread.sleep(interval);
} catch (Exception e) {
}
}
}
Consumer
public void run() {
while (true) {
try {
setStatus("getting");
int number=get(this);
int interval = ((int) (Math.random() * 10000));
this.setStatus("sleeping "+(interval/1000)+"secs");
Thread.sleep(interval);
} catch (Exception e) {
}
}
}
Networking
 There are two modes: connection oriented and
connectionless.
 The connection oriented mode works like telephone lines.
Before you can talk to another person over the phone, you
need to establish a circuit connecting you and the other
person. Then, you can use this circuit to transmit voice
signal. The signal will always arrive in the same order as they
are sent.
Connectionless mode
 The connectionless mode works like the post office. When
you send a letter to another person, the post office will
deliver the letter to that person. However, if you send many
letters to the same person, there is no guarantee that the
letter will arrive at the same order as they are sent.
IP address and Port
 Before we can communicate with a computer, we need to
know how to locate that computer first.
 Computers are identified by its IP address in the internet.
 An IP address consists of four bytes and are usually expressed
in the form of:
xxx.xxx.xxx.xxx
 Since IP address is difficult to remember, we usually use host
name instead.
Host name and domain name
server
 Note that IP addresses and host names do not form a one to
one relation.
 An IP address can map to zero, one or even more host
names.
 Similarly, a host name can also map to zero, one or even
more IP addresses.
port
 A computer can have many services. For example, a server
would usually provide services like http, ftp, telnet etc. So
when you want to talk to a computer, you need to specify
which service you want to use.
 This is done by specifying the port number corresponding to
the service.
port
 A port number is a 2 bytes integers starting from 1.
 Some common services use pre-defined port: ftp: 21, telnet:
23, http: 80 etc.
 So when two computers are connected using the connection
oriented mode, the connection is identified uniquely by the
ip addresses and the ports used by the two computer.
port 3334
IP: 123.3.24.22
port 234
IP: 202.40.219.235
A connection is uniquely identified by the IP addresses and port
numbers at the two ends.
Server
 The ip address and port number work like a telephone with
some extension. So you want to be a server, it is similar to
one who is wait for others to call. So the first thing he/she
needs to do is to let others to know the telephone number
and the extension number.
Server
 However, when other people want to talk to the server, there
is no need to use a particular telephone and extension. You
can use any one that is available.
Server
 If the server is a multithreaded server, then the server can be
talking to a number of clients at a time.
port 8242
IP: 223.33.44.103
port 3334
IP: 123.3.24.22
port 234
IP: 202.40.219.235
A connection is uniquely identified by the IP addresses and port
numbers at the two ends.
Server
 So, even though a server is waiting for requests at one port
only, it is possible for it to entertain many requests at the
same time.
Socket
 Socket is the term used to describe one end of a connection.
 So to create a connection between two computers, you first
need to have two sockets at the two ends.
Sockets
 There are two kinds of sockets, one on the server and one on
the client.
 As mentioned earlier, when you need to specify the port to
be used on the server side.
 In Java, ServerSocket is used to model sockets on the server
side.
ServerSocket
 the constructor
public ServerSocket(int port)
throws IOException
can be used to create a socket on the server side with the
given port. The constructor will throw IOException if there
is a problem in creating the server socket.
Socket
 After the ServerSocket is created, then we can make the
server listen to the port by invoking the accept method of
ServerSocket:
ServerSocket sSocket=new ServerSocket(4444);
Socket socket=sSocket.accept();
 When the accept method is invoked, the thread is blocked
until there is a request from a client for this service.
Socket
 Then, a Socket will be returned.
 As said earlier, a socket is one end of a network connection.
To start the communication, you need to get an input stream
and an output stream by using the method:
InputStream getInputStream() throws IOException
OutputStream getOutputStream() throws IOException
A single threaded server
 So a single threaded server would do something like this:
ServerSocket sSocket=new ServerSocket(11111);
while (true) {
Socket socket=sSocket.accept();
OutputStream outputStream=socket.getOutputStream();
InputStream inputStream=socket.getInputStream();
.... // we can do something about the input and output.
}
The client
 On the client side, there is no need to create a ServerSocket.
Instead, we would use a constructor of Socket:
public Socket(String host, int port) throws UnknownHostException,
IOException
 Note that we need to specify the host and the port number
here. To specify the host, you can either use the IP address or
the host name.
localhost
 If you have two computers, you can use one computer as the
server and the other as the client to test your network
program.
 However, if you only has one computer, how can you test a
network program?
 You can do that by using the loopback address: 127.0.0.1
which refers to your computer.
A simple server
 Let's write a simple single threaded server which accepts two
integers from a client and then returns the sum of the two
integers to the client.
public class MyServer {
static public void main(String st[]) {
try {
java.net.ServerSocket sSocket=new java.net.ServerSocket(11111);
while (true) {
java.net.Socket socket=sSocket.accept();
java.io.OutputStream output=socket.getOutputStream();
java.io.InputStream input=socket.getInputStream();
java.io.DataOutputStream dout=new java.io.DataOutputStream(output);
java.io.DataInputStream din=new java.io.DataInputStream(input);
int a1=din.readInt();
int a2=din.readInt();
dout.writeInt(a1+a2);
dout.close();
din.close();
socket.close();
}
}
catch (Exception e) {
}
}
}
public class MyClient {
public static void main(String st[]) {
try {
java.net.Socket socket=new java.net.Socket("127.0.0.1",11111);
java.io.OutputStream output=socket.getOutputStream();
java.io.InputStream input=socket.getInputStream();
java.io.DataOutputStream dout=new java.io.DataOutputStream(output);
java.io.DataInputStream din=new java.io.DataInputStream(input);
dout.writeInt(3);
dout.writeInt(4);
int result=din.readInt();
System.out.println("the result is "+result);
} catch (Exception e) {
}
}
}
A multithreaded server
 The previous server can only handle one request at a time.
This does not seem to be a problem as each request does not
last for too long.
 However, if a server needs to provide some computationally
intensive service, there is a need to have a multithreaded
server or else a client may have to wait for a long time before
it is served.
Multithreaded server
 In a multithreaded server, when there is an incoming request,
we would create a thread to handle the request.
 Now, lets rewrite the last simple server to be a multithreaded
server.
Multithreaded server
 First we create a class MyThread which is used to handle a
request. In our design, the constructor of MyThread has a
parameter of type Socket which is the socket returned from
the accept method of ServerSocket.
 Then the run method of MyThread would perform the
necessary operations.
public class MyThread extends Thread {
private java.net.Socket socket;
/** Creates a new instance of MyThread */
public MyThread(java.net.Socket socket) {
this.socket=socket;
}
public void run() {
try {
java.io.OutputStream output=socket.getOutputStream();
java.io.InputStream input=socket.getInputStream();
java.io.DataOutputStream dout=new java.io.DataOutputStream(output);
java.io.DataInputStream din=new java.io.DataInputStream(input);
int a1=din.readInt();
int a2=din.readInt();
dout.writeInt(a1+a2);
dout.close();
din.close();
socket.close();
} catch (Exception e) {}
}
}
public class MultiThreadedServer {
static public void main(String st[]) {
try {
java.net.ServerSocket sSocket=new java.net.ServerSocket(11111);
while (true) {
java.net.Socket socket=sSocket.accept();
MyThread thread=new MyThread(socket);
thread.start();
}
}
catch (Exception e) {
}
}
}