传统Socket编程传递POJO(使用JSON的方式)

来源:互联网 发布:勇士的荣耀网络直播 编辑:程序博客网 时间:2024/06/11 19:30

1、JSON序列化的工具类

import com.google.gson.Gson;public class GSONUtils {/** * 将给定的对象转换为Json *  * @param src * @return */public static String toJson(Object src) {Gson gson = new Gson();return gson.toJson(src);}/** * 将Json转换为,给定的对象 *  * @param json * @param clazz * @return */public static <T> T fromJson(String json, Class<T> clazz) {Gson gson = new Gson();return gson.fromJson(json, clazz);}}

2、对于客户端,请求信息的封装

public class RequestInfo {private String requestInfo;public RequestInfo() {}public RequestInfo(String requestInfo) {super();this.requestInfo = requestInfo;}public String getRequestInfo() {return requestInfo;}public void setRequestInfo(String requestInfo) {this.requestInfo = requestInfo;}@Overridepublic String toString() {return "RequestInfo [requestInfo=" + requestInfo + "]";}}

3、对于服务端,响应信息的封装

public class ResponseInfo {private String resposeInfo;public ResponseInfo() {}public ResponseInfo(String resposeInfo) {this.resposeInfo = resposeInfo;}public String getResposeInfo() {return resposeInfo;}public void setResposeInfo(String resposeInfo) {this.resposeInfo = resposeInfo;}@Overridepublic String toString() {return "ResponseInfo [resposeInfo=" + resposeInfo + "]";}}

4、客户端代码 

      4.1  对于获取客户端请求信息的处理 

// 客户端向服务端,发送数据// 同时接受,服务端响应的信息while (true) {// 1.接受客户端控制台的输入,并发送给服务端// 以方法的形式抽离出去了Scanner scanner = new Scanner(System.in);String requestInfo = scanner.nextLine();RequestInfo info = new RequestInfo(requestInfo);// 使用GSON序列化的方式sendDataToServer(out, GSONUtils.toJson(info));}

      4.2  对于响应信息的处理

response = reader.readLine();// 对服务端,返回的数据处理ResponseInfo info = GSONUtils.fromJson(response, ResponseInfo.class);System.out.println("Client接收到Server发来的数据: " + response);System.out.println("Client接收到Server发来的数据: " + info.getResposeInfo());

      4.3  完整的客户端代码

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.util.Scanner;public class Client {private String ADDRESS = null;private int PORT;private Socket socket = null;private BufferedReader in = null;private PrintWriter out = null;public void connect(String address, int port) {try {this.ADDRESS = address;this.PORT = port;socket = new Socket(ADDRESS, PORT);in = new BufferedReader(new InputStreamReader(socket.getInputStream()));out = new PrintWriter(socket.getOutputStream(), true);// 客户端向服务端,发送数据// 同时接受,服务端响应的信息while (true) {// 1.接受客户端控制台的输入,并发送给服务端// 以方法的形式抽离出去了Scanner scanner = new Scanner(System.in);String requestInfo = scanner.nextLine();RequestInfo info = new RequestInfo(requestInfo);// 使用GSON序列化的方式sendDataToServer(out, GSONUtils.toJson(info));// 2.接受服务端响应的数据,并处理// 因为处理,根据不同的业务,处理不同// 所以抽离出去,使用handleResponse(String response)函数处理// 在这里,只是简单的输出打印handleResponse(in);}} catch (Exception e) {e.printStackTrace();}}// 客户端,给服务端发送请求数据private static void sendDataToServer(PrintWriter writer, String requestInfo) {writer.println(requestInfo);}// 对服务端返回的数据,做处理// 这可以是一个逻辑,所有从上面的代码抽出来// 是的代码,看起来更加的整洁美观private static void handleResponse(BufferedReader reader) {String response;try {response = reader.readLine();// 对服务端,返回的数据处理ResponseInfo info = GSONUtils.fromJson(response, ResponseInfo.class);System.out.println("Client接收到Server发来的数据: " + response);System.out.println("Client接收到Server发来的数据: " + info.getResposeInfo());} catch (IOException e) {throw new RuntimeException(e);}}// 测试方法public static void main(String[] args) {new Client().connect("127.0.0.1", 8338);}}

5、服务端代码

import java.net.ServerSocket;import java.net.Socket;public class Server {public void listener(int port) {ServerSocket server = null;try {server = new ServerSocket(port);System.out.println("server start  port " + port + " ... ");HandlerExecutorPool executorPool = new HandlerExecutorPool(100, 500);// 进行阻塞,用于接收客户端的请求while (true) {Socket socket = server.accept();System.out.println("一个客户端连接上来了");// 利用线程池的线程,执行客户端的任务executorPool.execute(new ServerHandler(socket));}} catch (Exception e) {e.printStackTrace();}}// 开启服务器public static void main(String[] args) {new Server().listener(8338);}}

6、服务端Handler代码

      6.1  对于获取客户端请求信息的处理 

// 用于接收客户端的请求信息requestInfo = reader.readLine();// 如果有信息,就进行读取操作// 如果为null,就关闭socket连接,释放资源if (requestInfo != null) {// 打印查看,responseInfo信息System.out.println("Server: from client data is: "+ requestInfo);// 根据客户端的请求数据,服务端进行处理// getAnswer(String question),就是根据客户端的请求// 获取相应的数据信息(比如查询数据库)// 增加对客户端,序列化的处理RequestInfo info = GSONUtils.fromJson(requestInfo,RequestInfo.class);String resposeInfo = getAnswer(info.getRequestInfo());

      6.2  对于响应信息的处理

// 根据用户的请求,获取返回信息// 实际的开发,可以到数据库获取数据private String getAnswer(String question) {String answer = "请输入 who, 或者what, 或者where";if ("who".equals(question)) {answer = "我是莉莉";} else if ("what".equals(question)) {answer = "我是来帮你解闷的";} else if ("where".equals(question)) {answer = "我来自外太空";} else {answer = "请输入 who, 或者what, 或者where";}// 实际开发,可以根据请求信息// 到数据库查询数据,并且返回给客户端System.out.println(answer);ResponseInfo info = new ResponseInfo(answer);// 将结果以JSON的方式返回return GSONUtils.toJson(info);}

      6.3  完整的服务端代码

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;public class ServerHandler implements Runnable {private Socket socket;private BufferedReader reader;private PrintWriter writer;public ServerHandler(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {// 模拟线程池处理不及时Thread.sleep(1000);System.out.println(Thread.currentThread().getName());reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));writer = new PrintWriter(this.socket.getOutputStream(), true);// 用于处理客户端的请求,并返回信息给客户端while (true) {handle(reader, writer);}} catch (Exception e) {e.printStackTrace();} finally {// 释放资源CloseUtils.closeCloseable(reader, writer, socket);}}// 用于获取客户端的请求信息// 并将返回信息,发送给客户端private void handle(BufferedReader reader, PrintWriter writer) {String requestInfo = null;try {// 用于接收客户端的请求信息requestInfo = reader.readLine();// 如果有信息,就进行读取操作// 如果为null,就关闭socket连接,释放资源if (requestInfo != null) {// 打印查看,responseInfo信息System.out.println("Server: from client data is: "+ requestInfo);// 根据客户端的请求数据,服务端进行处理// getAnswer(String question),就是根据客户端的请求// 获取相应的数据信息(比如查询数据库)// 增加对客户端,序列化的处理RequestInfo info = GSONUtils.fromJson(requestInfo,RequestInfo.class);String resposeInfo = getAnswer(info.getRequestInfo());// 服务端,根据客户端的请求数据,返回的数据sendDataToClient(writer, resposeInfo);}} catch (IOException e) {// e.printStackTrace();// 释放资源CloseUtils.closeCloseable(reader, writer, socket);return;}}// 服务端,用于给客户端发送数据// 也就是将,根据客户端的请求的信息,获取的返回信息。返回给客户端// 客户端,给服务端发送请求数据private static void sendDataToClient(PrintWriter writer, String responseInfo) {writer.println(responseInfo);// 服务端写数据给客户端的时候,要执行flush()操作// 不然客户端,可能不会及时的接收到信息writer.flush();}// 根据用户的请求,获取返回信息// 实际的开发,可以到数据库获取数据private String getAnswer(String question) {String answer = "请输入 who, 或者what, 或者where";if ("who".equals(question)) {answer = "我是莉莉";} else if ("what".equals(question)) {answer = "我是来帮你解闷的";} else if ("where".equals(question)) {answer = "我来自外太空";} else {answer = "请输入 who, 或者what, 或者where";}// 实际开发,可以根据请求信息// 到数据库查询数据,并且返回给客户端System.out.println(answer);ResponseInfo info = new ResponseInfo(answer);// 将结果以JSON的方式返回return GSONUtils.toJson(info);}}

7、自定义线程池

import java.util.concurrent.ExecutorService;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class HandlerExecutorPool {private ExecutorService executor;/** *  * @param maxPoolSize *            线程池,最大的线程数 * @param queueSize *            阻塞队列的最大个数 */public HandlerExecutorPool(int maxPoolSize, int queueSize) {this.executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), maxPoolSize, //120L, TimeUnit.SECONDS, //new LinkedBlockingQueue<Runnable>(queueSize));}public void execute(Runnable task) {this.executor.execute(task);}}

8、关闭流的工具类

import java.io.Closeable;import java.io.IOException;public class CloseUtils {public static void closeCloseable(Closeable... closeables) {for (int i = 0; i < closeables.length; i++) {if (closeables[i] != null) {try {closeables[i].close();} catch (IOException e) {e.printStackTrace();}}}}}

1 0
原创粉丝点击