该例展示了多用户/服务器通信模型,包含三个文件: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