封装socket的通信协议完成文本通信

封装socket的通信协议完成文本通信 socket是典型的cs架构,由于client端通过OutputStream发送消息,server端通过InputStream接收消息。一般发送本文信息都是一条条发出去的,接收端无法得知每条消息的边界。所以对协议封装一下完成文本信息逐条发送并在服务端实时解析。
首先约定好协议的标准

public class Protocol { public static final int OPEN = 1; public static final int TALK = 2; public static final int QUIT = 3; }

【封装socket的通信协议完成文本通信】socket客户端的代码
public class EchoClient implements Closeable { private String host; private int port; private Socket client; public EchoClient(String host, int port) { this.host = host; this.port = port; try { client = new Socket(host, port); open(client); } catch (IOException e) { e.printStackTrace(); } }private void open(Socket client) { try { OutputStream outputStream = client.getOutputStream(); DataOutputStream write = new DataOutputStream(outputStream); write.write(Protocol.OPEN); write.flush(); } catch (IOException e) { e.printStackTrace(); } }public void sendMessage(String message) { try { byte[] data = https://www.it610.com/article/message.getBytes("UTF-8"); OutputStream outputStream = client.getOutputStream(); DataOutputStream write = new DataOutputStream(outputStream); write.writeByte(Protocol.TALK); write.writeInt(data.length); write.write(data); write.flush(); } catch (IOException e) { e.printStackTrace(); } }public void close() throws IOException { OutputStream outputStream = null; try { outputStream = client.getOutputStream(); DataOutputStream write = new DataOutputStream(outputStream); write.write(Protocol.QUIT); write.flush(); write.close(); } catch (IOException e) { e.printStackTrace(); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } client.close(); }public static void main(String[] args) { try (EchoClient client = new EchoClient("localhost", 55533)) { for (int i = 0; i < 5000; i++) { client.sendMessage(String.format("hello world %s", i)); } } catch (IOException e) { e.printStackTrace(); } } }

socket服务端的代码
public class EchoServer implements Closeable, Runnable { private int port; private ServerSocket server; private boolean RUNNINGSTATE = false; public EchoServer(int port) { this.port = port; try { server = new ServerSocket(port); } catch (IOException e) { e.printStackTrace(); } }public void listener() { Socket client = null; try { client = server.accept(); } catch (IOException e) { e.printStackTrace(); } accept(client); }@Override public void run() { listener(); }public void onOpen(Socket socket) { RUNNINGSTATE = true; System.out.println(String.format("新连接%s进来了", socket.getInetAddress())); }public void onClose(Socket socket) { System.out.println(String.format("客户端%s退出连接", socket.getInetAddress())); }public void handle(String message) { System.out.println(message); }public void accept(Socket socket) { try { InputStream inputStream = socket.getInputStream(); BufferedInputStream read = new BufferedInputStream(inputStream); int type = 0; while ((type = read.read()) != -1) { switch (type) { case Protocol.OPEN: onOpen(socket); break; case Protocol.QUIT: onClose(socket); break; case Protocol.TALK: byte[] buffer = new byte[1024]; int len = readInt(read); int offset = 0; StringBuilder sb = new StringBuilder(); while (len > 0 && (offset = read.read(buffer, 0, len < buffer.length ? len : buffer.length)) != -1) { sb.append(new String(buffer, 0, offset, "UTF-8")); len -= offset; } handle(sb.toString()); } } read.close(); inputStream.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } }public final int readInt(InputStream in) throws IOException { int ch1 = in.read(); int ch2 = in.read(); int ch3 = in.read(); int ch4 = in.read(); if ((ch1 | ch2 | ch3 | ch4) < 0) throw new EOFException(); return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); }public boolean isRUNNINGSTATE() { return RUNNINGSTATE; }public static void main(String[] args) { EchoServer echoServer = new EchoServer(55533); echoServer.run(); }@Override public void close() throws IOException { server.close(); } }

然后启动服务端和客户端即可完成消息的发送和接受

    推荐阅读