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();
}
}
|