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;

    }
相关推荐
懂得节能嘛.3 分钟前
【动态配置中心】Java+Redis构建动态配置中心
java·开发语言·redis
专注于大数据技术栈4 分钟前
Java中JDK、JRE、JVM概念
java·开发语言·jvm
YuanlongWang7 分钟前
C# 基础——值类型与引用类型的本质区别
java·jvm·c#
Kay_Liang32 分钟前
大语言模型如何精准调用函数—— Function Calling 系统笔记
java·大数据·spring boot·笔记·ai·langchain·tools
自由的疯1 小时前
Java 如何学习Docker
java·后端·架构
自由的疯1 小时前
Java Docker本地部署
java·后端·架构
007php0071 小时前
猿辅导Java面试真实经历与深度总结(二)
java·开发语言·python·计算机网络·面试·职场和发展·golang
摇滚侠1 小时前
Spring Boot 3零基础教程,WEB 开发 内容协商机制 笔记34
java·spring boot·笔记·缓存
一勺菠萝丶1 小时前
在 macOS 上用 Docker 为 Java 后端 & 常见开发需求搭建完整服务(详尽教程)
java·macos·docker
顾漂亮1 小时前
JVM底层攻坚
java·jvm·spring