IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> socket模拟websocket握手进行通讯 -> 正文阅读

[网络协议]socket模拟websocket握手进行通讯

package com.example.tbyoung;

import com.alibaba.fastjson.JSON;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class TCPServer {
    private int port;
    private boolean isFinished;
    private ServerSocket serverSocket;
    private ArrayList<SocketThread> socketThreads;


    public TCPServer(int port) {
        this.port = port;
        socketThreads = new ArrayList<>();
    }

    public static String he_der = "";
    public static HashMap<String, String> map;

    public void start() {
        isFinished = false;
        try {
            //创建服务器套接字,绑定到指定的端口
            serverSocket = new ServerSocket(port);
            //等待客户端连接
            while (!isFinished) {
                Socket socket = serverSocket.accept();//接受连接
                //创建线程处理连接
                SocketThread socketThread = new SocketThread(socket);
                socketThreads.add(socketThread);
                socketThread.start();
            }
        } catch (IOException e) {
            isFinished = true;
        }
    }


    public void stop() {
        isFinished = true;
        for (SocketThread socketThread : socketThreads) {
            socketThread.interrupt();
            socketThread.close();
        }
        try {
            if (serverSocket != null) {
                serverSocket.close();
                serverSocket = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private class SocketThread extends Thread {

        private Socket socket;
        private InputStream in;
        private OutputStream out;

        SocketThread(Socket socket) {
            this.socket = socket;
            try {
                in = socket.getInputStream();
                out = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {
            while (!isInterrupted()) {
                if (in == null) {
                    return;
                }
                try {
                    int available = in.available();
                    if (available > 0) {
                        byte[] buffer = new byte[1024];
                        int size = in.read(buffer);
                        if (size > 0) {
                            String data = new String(buffer, 0, size);
                            if(data.indexOf("GET") !=-1) {
                                he_der = data;
                                map = getRequestHeader(data.getBytes(StandardCharsets.UTF_8));
                                String s = getResponseHeader(map);
                                System.out.println("握手成功!!!!!!!!");
                                out.write(s.getBytes());
                            }else {
                                /*
                                    因为WebSocket发送过来的数据遵循了一定的协议格式,
                                    其中第3个~第6个字节是数据掩码。
                                    从第7个字节开始才是真正的有效数据。
                                    因此程序使用第3个~第6个字节对后面的数据进行了处理
                                */
                                for (int i = 0; i < size - 6; i++) {
                                    buffer[i + 6] = (byte) (buffer[i % 4 + 2] ^ buffer[i + 6]);
                                }
                                String content = new String(buffer, 6, size - 6, "UTF-8");
                                // 显示读取得到的数据
                                System.out.println("接收的内容:" + content);
                                // 发送数据时,第一个字节必须与读到的第一个字节相同
                                byte[] pushHead = new byte[2];
                                pushHead[0] = buffer[0];
                                String pushMsg = content + "呀!";
                                // 发送数据时,第二个字节记录发送数据的长度
                                pushHead[1] = (byte) pushMsg.getBytes("UTF-8").length;
                                // 发送前两个字节
                                out.write(pushHead);
                                // 发送有效数据
                                out.write(pushMsg.getBytes("UTF-8"));
                                out.flush();
                            }

                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        void close() {

            try {
                if (in != null) {
                    in.close();
                }

                if (out != null) {
                    out.close();
                }

                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public static HashMap<String, String> getRequestHeader(byte[] data) {
        String requestHeader = new String(data);
        requestHeader = requestHeader.substring(0, requestHeader.indexOf("\r\n\r\n"));
        String[] reqarr = requestHeader.split("\r\n");
        HashMap<String, String> reqHeader = new HashMap<String, String>();
        for (int i = 0; i < reqarr.length; i++) {
            String requestHeaderLine = reqarr[i];
            if (requestHeaderLine.toUpperCase().startsWith("GET") || requestHeaderLine.toUpperCase().startsWith("POST")) {
                String[] first = requestHeaderLine.split(" ");
                if (first.length == 3) {
                    String method = first[0];
                    String location = first[1].replaceAll("\\s", "");
                    String protocol = first[2].split("/")[0];
                    String protocolVersion = first[2].split("/")[1];
                    reqHeader.put("Method", method);
                    reqHeader.put("Location", location);
                    reqHeader.put("Protocol", protocol);
                    reqHeader.put("ProtocolVersion", protocolVersion);
                }
            } else {
                String[] reqlinearr = requestHeaderLine.split(":");
                if (reqlinearr.length == 2) {
                    String key = reqlinearr[0];
                    String value = reqlinearr[1].replaceAll("\\s", "");
                    reqHeader.put(key, value.replaceAll("\\s", ""));
                }
            }
        }
        return reqHeader;
    }

    public static String getResponseHeader(HashMap<String, String> reqHeader) {
        String originKey = reqHeader.get("Sec-WebSocket-Key") + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
        java.security.MessageDigest alga = null;
        byte[] digesta = null;
        try {
            alga = java.security.MessageDigest.getInstance("SHA-1");
            alga.update(originKey.getBytes());
            digesta = alga.digest();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        byte[] respKey = Base64.getEncoder().encode(digesta);
        String header = "HTTP/1.1 101 Switching Protocols\r\n" +
                "Upgrade: Websocket\r\n" +
                "Connection: Upgrade\r\n" +
                "Sec-WebSocket-Accept: " + new String(respKey) + "\r\n\r\n";
        return header;
    }

    public static void main(String[] args) {
        TCPServer tcpServer = new TCPServer(8888);
        new Thread(() -> tcpServer.start()).start();
    }
}

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 08:19:50  更:2021-09-19 08:20:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年6日历 -2024/6/27 2:04:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码