Java网络编程学习A轮_05_Socket编程

示例代码:
https://github.com/gordonklg/study,socket module

A. Socket 编程简单例子

最简单的 Socket 编程是通过回车/换行符,整行读取字符串。网上代码随便抄抄便是。

gordon.study.socket.basic.LineSeparateEchoServer.java
代码略

B. 简单的自定义协议

对于传输内容包含回车/换行符的通讯需求,可以使用自定义协议。

此处演示一个很简单的协议:

  • 第一个字节代表类型,1表示为文本,0表示结束通讯,可扩展其它类型,如 jpeg、png、wav
  • 第2-3个字节代表整个报文段长度
  • 后面为消息内容

gordon.study.socket.basic.CustomProtocolPrintServer.java

public class CustomProtocolPrintServer {

    @SuppressWarnings("resource")
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 3; i++) {
            new Thread(new CustomProtocolPrintClient()).start();
        }
        ServerSocket serverSocket = new ServerSocket(8888);
        while (true) {
            Socket socket = serverSocket.accept();
            new Thread(new PrintServerHandler(socket)).start();
        }
    }

    private static class PrintServerHandler implements Runnable {

        private Socket socket;

        public PrintServerHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            try {
                DataInputStream dis = new DataInputStream(socket.getInputStream());
                while (true) {
                    int type = dis.read();
                    if (type == 0) {
                        break;
                    }
                    int length = (dis.readByte() & 0xFF) << 8 | dis.readByte() & 0xFF;
                    byte[] content = new byte[length - 3];
                    dis.readFully(content);
                    System.out.println("server received: " + new String(content));
                }
                dis.close();
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

gordon.study.socket.basic.CustomProtocolPrintClient.java

public class CustomProtocolPrintClient implements Runnable {

    private String[] msgArray = { "ni hao", "hello", "chi le ma?", "你瞅啥?", "hi dude" };

    @Override
    public void run() {
        try (Socket socket = new Socket()) {
            socket.connect(new InetSocketAddress(8888));
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            for (int i = 0; i < 3; i++) {
                int pos = ThreadLocalRandom.current().nextInt(msgArray.length);
                long sleepTime = ThreadLocalRandom.current().nextLong(1500) + 250;
                sendMsg(msgArray[pos], dos);
                Thread.sleep(sleepTime);
            }
            dos.writeByte(0);
            dos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void sendMsg(String msg, DataOutputStream dos) throws Exception {
        byte[] bytes = msg.getBytes();
        int totalLength = 3 + bytes.length;
        dos.writeByte(1);
        dos.write((byte) (totalLength >> 8 & 0xFF));
        dos.write((byte) (totalLength & 0xFF));
        dos.write(bytes);
    }
}

原文地址:https://www.cnblogs.com/gordonkong/p/7434589.html