Some of you may not have done a network socket programmming, but network programmings using sockets are now widely used.
In this tutorial, we will go through a simple server-client program and learn how to use some design patterns.
Fist, the following is the simple client side code (wihout any Design Pattern)
import java.*;
import java.io.*;
/* client side */
public class MySocket {
String host = "localhost";
int port = 25565; /* use unused port */
spring framework documentationpublic static void main( String [] args ) throws Exception {
new MySocket();
}
MySocket( ) throws Exception {
String line;
/* read one line from the std in */
BufferedReader con = new BufferedReader( new InputStreamReader( System.in ) );
/* create the address to connect */
InetSocketAddress addr = new InetSocketAddress( host, port );
/* create socket */
Socket sock = new Socket();
/* connect it : time out 10 seconds */
/* Read/write object for the socket */
OutputStream os = OutputStream();
PrintStream ps = new PrintStream( os );
InputStream is = InputStream();
BufferedReader br = new BufferedReader( new InputStreamReader( is ) );
while( (line = adLine()) != null ) {
/* send one line from the standard input to the socket */
ps.println( line );
ps.flush();
/* if the message is "quit", then quit */
if( line.equals( "quit" ) ) {
break;
}
/* read */
String s = br.readLine();
System.out.println( s );
}
sock.close();
}
}
On the server‐side you would need to use a thread because the server needs to process multiple conc
urrent requests from multiple client. The server waits for a connection through the specified port and when there is a connection, it creates a dedicated thread.
Therefore, the main program just does creating the socket (java.ServerSocket) and just wait and create a thread.
Here is the Server code:
import java.*;
import java.io.*;
/* Server */
public class MyServer {
int port = 25565; /* use the same port number */
public static void main( String [] args ) throws Exception {
new MyServer();
}
MyServer( ) throws Exception {
/* just create a socket and wait for a connection */
ServerSocket ss = new ServerSocket( port );
while( true ) {
/* connection requested! */
Socket sock = ss.accept();
/* let each thread to handle each connection */
ServerThread st = new ServerThread( sock );
st.start();
}
}
}
/* run a separate thread for each connection */
class ServerThread extends Thread {
Socket sock; /* socket representing the connection */
InetAddress ia; /* address of the connection established */
BufferedReader br; /* interface for reading */
PrintStream ps; /* interface for writing */
ServerThread( Socket s ) throws Exception {
/* make sure to create the read/write interface in the constructor.
The rest can be obtained from Socket object/*
sock = s;
ia = InetAddress();
InputStream is = InputStream();
br = new BufferedReader( new InputStreamReader( is ) );
OutputStream os = OutputStream();
ps = new PrintStream( os );
}
/* actual thread */
public void run() {
String line;
try {
while( (line = br.readLine()) != null ) {
/* just print out whatever read */
System.out.println( "read from " + ia + ": " + line );
/* stop when “quit” is received */
if( line.equals( "quit" ) ) {
break;
}
/* just echo it */
ps.println( line );
ps.flush();
}
System.out.println( "Disconnected: " + ia );
} catch( IOException e ) {
e.printStackTrace();
}
try {
/* close() everything opened. */
br.close();
ps.close();
sock.close();
} catch( IOException e ) {
/* NOP */
}
}
}
Now here is the problem. This client‐server system is doing extremely simple thig:
1)open port (client and server side),
2)send request to the server, (client)
3)listen to the port for connection request (server)
4)send a message to the server (client)
5)read a message from a client (server)
However, the code itself seems to be rather complicated. One of reasons is that objects responsible for “read” and “wirte” are separated and you need to create various java.io package objects.
So, we will try to apply a design pattern, which will put all related items together.
Here, you task is to apply “Façade” design pattern to put all read/write functions in one RWSocket class.
Façade: This design pattern will provide an unified interface to multiple interfaces exist in the
system. Façade design pattern defines the high‐level interface
Now let’s think about how we can use this client‐server mechanism to implement timer function, which you had to design and implement for your Assignment 3.
We can design a system, which stop reading information from a socket when the specified time laps. To achieve this you can monitor socket time out like:
RWSocket rw = new RWSocket(socket);
String s = rw.red(1000);
if (s == null) {
if (rw.getStatus() == RWSocket.TIMEOUT) {
/
/do timeout process
} else {
// connection failur process
}
} else {
// normal process
}
Your first task is to design this RWSocket class which can be used as show in the following code:
import java.*;
import java.io.*;
import your.class.RWSocket;
/
* Server */
public class MyServer2 {
int port = 25565; /* pick unused port number */
public static void main( String [] args ) throws Exception {
new MyServer2();
}
MyServer2( ) throws Exception {
/* Create a ServerSocket object and wait for a connection */
ServerSocket ss = new ServerSocket( port );
while( true ) {
/* connection request! */
Socket sock = ss.accept();
/* let a separate thread to handle each connection */
ServerThread2 st = new ServerThread2( sock );
st.start();
}
}
}
/* run a thread for each connection */
class ServerThread2 extends Thread {
RWSocket rw; /* socket */
InetAddress ia; /* destination address */
ServerThread2( Socket s ) throws Exception {
rw = new RWSocket(s);
ia = s.getInetAddress();
}
/* actual thread body */
public void run() {
String line;
while( (line = rw.read()) != null ) {
/* communication stop with “quit” messge */
if( line.equals( "quit" ) ) {
break;
}
/* just echo(ECHO) */
rw.write( line );
}
System.out.println( "Disconnected: " + ia );
try {
rw.close(); /* just one close() */
} catch( IOException e ) {
/* NOP */
}
}
}
The following can be used to assist designing this RWSocket class:
/* your package name*/
u.mysocket;
import java.io.PrintStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.Socket;
import java.SocketException;
import java.SocketTimeoutException;
/
* Use the Façade design pattern to put all Socket related Read/Write (or IO) together. */
public class RWSocket {
//...
/* Error status */
public static final int NONE = 0;
/* SocketException represent that the socket is closed*/
public static final int CLOSED = 1;
/* SocketTimeoutException will cause TIMEOUT error return */
public static final int TIMEOUT = 2;
/* IOException indicate very bad IO error */
public static final int IO_ERROR = 3;
private int status = NONE;
/* constructors */
public IOSocket( ) { }
public IOSocket( Socket s ) throws IOException {
//.....
}
public IOSocket( String connect, int port ) throws IOException { // ....
}
/* set a socket */
public void set( Socket s ) throws IOException {
//...
}
/* provide error status */
public int getStatus() { return status; }
/* return socket */
public Socket getSocket() { return sock; }
// The following would the set of unified interface.
/* deal with read()’s exception */
public String read( ) {
status = NONE;
try {
...
} catch ( SocketTimeoutException e ) {
status = TIMEOUT;
} catch( SocketException e ) {
status = CLOSED;
} catch( IOException e ) {
status = IO_ERROR;
}
return null;
}
/* time out version!!!! */
public String read( int timeout ) {
status = NONE;
try {
...
return ret;
} catch ( SocketTimeoutException e ) {
status = TIMEOUT;
} catch( SocketException e ) {
status = CLOSED;
} catch( IOException e ) {
status = IO_ERROR;
}
return null;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论