• 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);
        }
    }
    
    
  • 相关阅读:
    mysql如何解决幻读 孙龙
    ssh服务 孙龙
    apipost动态获取登录token,其他接口同步调用
    Linux下快速删除大文件
    运行jmeter的serverAgent源码报错:java.lang.UnsatisfiedLinkError: org.hyperic.sigar.Cpu.gather
    获取某个进程占用内存比例
    获取某个进程占用CPU比例,并将执行结果存到文件中
    svn将代码提交至本地仓库
    WebDriverWait(WebDriver driver, long timeoutInSeconds) 已弃用,如何替代
    查看linux系统内存和磁盘总大小
  • 原文地址:https://www.cnblogs.com/gordonkong/p/7434589.html
Copyright © 2020-2023  润新知