https://editor.csdn.net/md/?articleId=129899173
可以先看看上一篇Socket编程
一个HTTP Server本质上是一个TCP服务器,我们先用TCP编程的多线程实现的服务器端框架:
package mytest;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(8080); // 监听指定端口
System.out.println("server is running...");
for (; ; ) {
Socket sock = ss.accept();
System.out.println("connected from " + sock.getRemoteSocketAddress());
Thread t = new Handler(sock);
t.start();
}
}
}
class Handler extends Thread {
Socket sock;
public Handler(Socket sock) {
this.sock = sock;
}
public void run() {
try (InputStream input = this.sock.getInputStream()) {
try (OutputStream output = this.sock.getOutputStream()) {
handle(input, output);
}
} catch (Exception e) {
try {
this.sock.close();
} catch (IOException ioe) {
}
System.out.println("client disconnected.");
}
}
private void handle(InputStream input, OutputStream output) throws IOException {
System.out.println("Process new http request...");
var reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
var writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
// 读取HTTP请求:
boolean requestOk = false;
String first = reader.readLine();
if (first.startsWith("GET / HTTP/1.")) {
requestOk = true;
System.out.println(first);
}
for (; ; ) {
String header = reader.readLine();
if (header.isEmpty()) { // 读取到空行时, HTTP Header读取完毕
break;
}
System.out.println(header);
}
System.out.println(requestOk ? "Response OK" : "Response Error");
if (!requestOk) {
// 发送错误响应:
writer.write("HTTP/1.0 404 Not Found\r\n");
writer.write("Content-Length: 0\r\n");
writer.write("\r\n");
writer.flush();
} else {
// 发送成功响应:
String data = "<html><body><h1>Hello, world!</h1></body></html>";
int length = data.getBytes(StandardCharsets.UTF_8).length;
writer.write("HTTP/1.0 200 OK\r\n");
writer.write("Connection: close\r\n");
writer.write("Content-Type: text/html\r\n");
writer.write("Content-Length: " + length + "\r\n");
writer.write("\r\n"); // 空行标识Header和Body的分隔
writer.write(data);
writer.flush();
}
}
}
结果如下:
D:\Develop\Java\bin\java.exe "-javaagent:D:\Develop\Idea\IntelliJ IDEA 2021.2.2\lib\idea_rt.jar=4413:D:\Develop\Idea\IntelliJ IDEA 2021.2.2\bin" -Dfile.encoding=UTF-8 -classpath F:\IdeaProjects\OnJava\out\production\OnJava;H:\jars\gson-2.9.0.jar mytest.Server
server is running...
connected from /[0:0:0:0:0:0:0:1]:4416
Process new http request...
GET / HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Microsoft Edge";v="111", "Not(A:Brand";v="8", "Chromium";v="111"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36 Edg/111.0.1661.62
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: _xsrf=2|9246d0ad|ccb62e4eef8d1c241a905eda53e56abc|1680267744; username-localhost-8888="2|1:0|10:1680534275|23:username-localhost-8888|44:ZTU0MjIxMDIyNGFkNDlkYmExN2I4ODM3YWQ2NTFmZTY=|6a1edf20939ecf9246407626cc7143c47dacee0fb07b334e3571f3cd432b492d"
Response OK
connected from /[0:0:0:0:0:0:0:1]:4417
Process new http request...
client disconnected.
Process finished with exit code 130