java实现websocket握手协议

java 复制代码
String str = new String(data, CHARSET);
        String[] arr = str.split("\r\n");
        String[] temp = arr[0].split(" ");
        Map<String, String> map = this.toMap(arr);
        String base64 = generateWebSocketAccept((String)map.get("Sec-WebSocket-Key"));
        StringBuffer sb = new StringBuffer(200);
        sb.append(temp[2]).append(" 101 Switching Protocols\r\n");
        sb.append("Upgrade: websocket\r\n");
        sb.append("Connection: Upgrade\r\n");
        sb.append("Sec-WebSocket-Accept: ").append(base64).append("\r\n\r\n");

其中最重要的是最后几个换行不要丢,将字符串转成byte[]写给客户端即可

java 复制代码
public static String generateWebSocketAccept(String webSocketKey) {
        System.out.println(webSocketKey);
        try {
            String acc = webSocketKey + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
            MessageDigest sh1 = MessageDigest.getInstance("SHA1");
            sh1.update(acc.getBytes(CHARSET), 0, acc.length());
            return Base64.getEncoder().encodeToString(sh1.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-1 algorithm not found", e);
        }
    }

下面是服务器向客户端发送消息

java 复制代码
public byte[] doSend(String mess) throws IOException{
        byte[] rawData = mess.getBytes();

        int frameCount  = 0;
        byte[] frame = new byte[10];

        frame[0] = (byte) 129;

        if(rawData.length <= 125){
            frame[1] = (byte) rawData.length;
            frameCount = 2;
        }else if(rawData.length >= 126 && rawData.length <= 65535){
            frame[1] = (byte) 126;
            int len = rawData.length;
            frame[2] = (byte)((len >> 8 ) & (byte)255);
            frame[3] = (byte)(len & (byte)255);
            frameCount = 4;
        }else{
            frame[1] = (byte) 127;
            int len = rawData.length;
            frame[2] = (byte)((len >> 56 ) & (byte)255);
            frame[3] = (byte)((len >> 48 ) & (byte)255);
            frame[4] = (byte)((len >> 40 ) & (byte)255);
            frame[5] = (byte)((len >> 32 ) & (byte)255);
            frame[6] = (byte)((len >> 24 ) & (byte)255);
            frame[7] = (byte)((len >> 16 ) & (byte)255);
            frame[8] = (byte)((len >> 8 ) & (byte)255);
            frame[9] = (byte)(len & (byte)255);
            frameCount = 10;
        }

        int bLength = frameCount + rawData.length;

        byte[] reply = new byte[bLength];

        int bLim = 0;
        for(int i=0; i<frameCount;i++){
            reply[bLim] = frame[i];
            bLim++;
        }
        for(int i=0; i<rawData.length;i++){
            reply[bLim] = rawData[i];
            bLim++;
        }

        return reply;

    }
相关推荐
河阿里5 分钟前
Java包装类(Wrapper):自动装箱拆箱机制与类型转换的那些坑
java·开发语言
小宇的天下6 分钟前
Virtuoso 技巧---被锁定无法编辑的文件解锁
java
晓杰'28 分钟前
Balatro后端进阶(1):自定义NestJS WebSocket Adapter实现消息拦截
后端·websocket·typescript·node.js·游戏开发·nestjs·wsadapter
微风欲寻竹影29 分钟前
Java数据结构——栈(Stack)详解
java·开发语言·数据结构
Makoto_Kimur32 分钟前
Java 后端面试场景题:页面刷新后一直转圈,应该怎么排查?
java·开发语言·面试
ch.ju1 小时前
Java Programming Chapter 3——Default value of array
java·开发语言
bandaoyu1 小时前
【CUDA】store/load普通访存 vs 非临时(Non-Temporal)访存
java·开发语言·redis
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第53题】【JVM篇】第13题:JVM采用什么算法判断一个对象是否需要被回收?
java·jvm·算法·面试
逍遥德1 小时前
常见的任务调度框架介绍
java·spring boot·中间件
jiayong231 小时前
Memory 写入、检索与纠错机制:让 Agent 记住,也让它忘对
java·服务器·网络·hermes