该例展示了多用户/服务器通信模型,包含三个文件:Server.java ServerThread.java 和Client.java类。其中ServerThread类支持多线程,为客户提供的所有操作都封装到该类中,该类的构造方法ServerThread(Socket socket)接收一个套接字对象,用来与客户进行数据通信。Server类是一个应用程序,其main方法中通过一个无限的whlie循环,等待并监听多个用户连接请求(本例中只演示了一个客户请求),每个客户的连接都由服务器端的一个单独线程来处理,如此可实现多用户机/服务器之间的通信。
Server类的代码如下:
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * Server类接收客户端的套接字请求,然后创建一个ServerThread线程来处理请求 * @author Administration * */ public class Server { public static void main(String[] args) { System.out.println("等待连接。。。"); try { //1.创建一个套接字对象serverSocket,设置端口号为6666 ServerSocket serverSocket = new ServerSocket(6666); Socket clientSocket = null; //2.监听套接字响应,一旦获得相应,则新建一个Serverhread类来处理这个响应 while(true) { clientSocket = serverSocket.accept();//监听 new ServerThread(clientSocket); } } catch (IOException e) { e.printStackTrace(); } } }
ServerThread类的代码如下:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; public class ServerThread extends Thread { //客户端靠套接字 private Socket clientSocket = null; //客户端输入流 private InputStream clientInput = null; //客户端输出流 private OutputStream clientOutput = null; //1.首先从构造方法中获得客户端的套接字请求,创建向客户端输入和输出的流,启动线程指执行接下来的请求 public ServerThread(Socket socket) throws IOException { clientSocket = socket; clientInput = clientSocket.getInputStream(); clientOutput = clientSocket.getOutputStream(); this.start(); } //2.线程启动后,通过缓冲流来获取从客户端传来的数据并进行分析,如果传过来的是“over”,则终止线程并关闭端口; //反之,则计算从客户端传过来的数值对应于正方形边长的面积,并将返回结果返回客户端,之后关闭端口 public void run() { try { //构建缓冲输入流,获取客户端传过来的数据 BufferedReader bufReader = new BufferedReader(new InputStreamReader(clientInput)); //按行读取输入流内容(数据) String strLine = bufReader.readLine(); //判断输入流数据 if("OVER".equalsIgnoreCase(strLine)) { //创建输出流,传递“over”信息,表示连接结束 PrintWriter printWriter = new PrintWriter(clientOutput,true); printWriter.println("连接OVER"); }else { //输入正方形边长,并输出边长及面积 double side = Double.parseDouble(strLine); side = Double.parseDouble(strLine); System.out.println("Side of Square Received:"+side); double squareArea = side*side; String str = "Side:"+side+"Square:"+squareArea; //创建输出流向客户端传递运算结果 PrintWriter printWriter = new PrintWriter(clientOutput,true); printWriter.println(str); System.out.println("Finish sending to client!"); } } catch (IOException e) { e.printStackTrace(); }finally { //关闭流和端口 try { clientInput.close(); clientOutput.close(); clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
客户端Client类代码如下:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner; /** * 客户端类 * @author Administration * */ public class Client { public static void main(String[] args) { Socket socket = null; try { //1.根据端口号创建与服务器端的连接 socket = new Socket("127.0.0.1",6666); //2.客户端从获取用户在控制台输入的信息 //通过Scanner获取键盘输入的值 System.out.println("Input Side:"); Scanner keyInput = new Scanner(System.in); //按行读取键盘输入 String strLine = keyInput.nextLine(); //3.创建客户端的输入流和输出流,将用户输入的信息发送到服务器端,之后再接收来自服务器端的运算结果 //获取服务器输入流 OutputStream outputStream = socket.getOutputStream(); //获取服务器输出流 InputStream inputStream = socket.getInputStream(); //通过PrintWriter输出流向服务器传数据 PrintWriter printWriter = new PrintWriter(outputStream,true); printWriter.println(strLine); BufferedReader bufdReader = new BufferedReader(new InputStreamReader(inputStream)); System.out.println(bufdReader.readLine()); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }finally { try { //4.关闭套接字和流 socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
服务器端的运行结果:
等待连接。。。 Side of Square Received:5.0 Finish sending to client!
客户端的运行结果:
Input Side: 5 Side:5.0 Square:25.0