当然可以!下面我会给你一个完整的 Java 示例,实现一个支持 HTTP/1.1 长连接(Keep-Alive) 的简单 Web 服务器。这个服务器能处理多个请求,并在同一连接上保持通信,直到客户端关闭或超时。
核心思路
使用 ServerSocket 接收客户端连接。
使用 Socket 的输入输出流读取 HTTP 请求并发送响应。
检查 HTTP 头中的 Connection 字段:
如果是 Connection: keep-alive,则保持连接。
如果是 Connection: close 或 HTTP/1.0,关闭连接。
处理超时,避免服务器无限等待。
支持简单静态响应(你可以扩展成读取文件)。
示例代码
import java.io.*;
import java.net.*;
import java.util.*;
public class KeepAliveHttpServer {
private static final int PORT = 8080;
private static final int TIMEOUT = 5000; // 5秒超时
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("HTTP 1.1 Keep-Alive Server started on port " + PORT);
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("Accepted connection from " + clientSocket.getInetAddress());
// 交给线程处理
new Thread(() -> handleClient(clientSocket)).start();
}
}
private static void handleClient(Socket socket) {
try {
socket.setSoTimeout(TIMEOUT); // 设置读取超时
InputStream input = socket.getInputStream();
OutputStream output = socket.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
PrintWriter writer = new PrintWriter(output, true);
boolean keepAlive = true;
while (keepAlive) {
// 读取请求行
String requestLine = reader.readLine();
if (requestLine == null || requestLine.isEmpty()) break;
System.out.println("Request: " + requestLine);
// 读取请求头
Map<String, String> headers = new HashMap<>();
String line;
while (!(line = reader.readLine()).isEmpty()) {
int idx = line.indexOf(":");
if (idx > 0) {
String key = line.substring(0, idx).trim();
String value = line.substring(idx + 1).trim();
headers.put(key.toLowerCase(), value);
}
}
// 检查 Connection 字段
String connectionHeader = headers.get("connection");
if (connectionHeader != null) {
keepAlive = connectionHeader.equalsIgnoreCase("keep-alive");
} else {
// HTTP/1.1 默认长连接
keepAlive = true;
}
// 构建响应
String body = "<html><body><h1>Hello, HTTP 1.1 Keep-Alive!</h1></body></html>";
int contentLength = body.getBytes().length;
writer.print("HTTP/1.1 200 OK\r\n");
writer.print("Content-Type: text/html\r\n");
writer.print("Content-Length: " + contentLength + "\r\n");
if (keepAlive) {
writer.print("Connection: keep-alive\r\n");
} else {
writer.print("Connection: close\r\n");
}
writer.print("\r\n"); // 空行表示头结束
writer.print(body);
writer.flush();
}
} catch (SocketTimeoutException e) {
System.out.println("Connection timed out.");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
System.out.println("Connection closed.");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
关键点解释
长连接处理
HTTP/1.1 默认启用长连接。
通过 Connection: close 可以强制关闭。
服务器循环读取请求,直到超时或客户端关闭。
超时机制
socket.setSoTimeout(TIMEOUT) 防止客户端挂起导致服务器阻塞。
并发处理
每个客户端连接由一个线程处理,避免阻塞主线程。
响应头
必须包含 Content-Length,浏览器才知道响应结束。
测试方法
运行 Java 服务器:
java KeepAliveHttpServer
用浏览器访问:
http://localhost:8080
用 curl 测试长连接:
curl -v --http1.1 http://localhost:8080
curl -v --http1.1 -H "Connection: keep-alive" http://localhost:8080
你会看到同一个 TCP 连接可以处理多个请求。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70050070/viewspace-3117737/ ,如需转载,请注明出处,否则将追究法律责任。