java编程实现一个HTTP服务器程序和HTTP客户端程序,使用线程池编程技术处理客户端请求,2. 实现GET、HEAD和POST请求,对客户端发送的不同请求给予正确响应,支持多客户端同时访问,使用cookie编程技术保存和传递会话状态信息
时间: 2023-09-18 18:08:02 浏览: 114
网络编程实验:HTTP服务器 java实现
以下是一个简单的Java HTTP服务器程序和HTTP客户端程序的实现,其中使用了线程池技术处理客户端请求,支持GET、HEAD和POST请求,并使用cookie保存和传递会话状态信息。
HTTP服务器程序:
```java
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;
public class HTTPServer {
private static final int DEFAULT_PORT = 8080;
private static final int THREAD_POOL_SIZE = 10;
private static final String SESSION_ID_COOKIE_NAME = "session_id";
private static final long SESSION_TIMEOUT = 60000; // 1 minute
private ServerSocket serverSocket;
private ExecutorService threadPool;
private Map<String, Session> sessions;
public HTTPServer(int port) {
try {
serverSocket = new ServerSocket(port);
threadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
sessions = new ConcurrentHashMap<>();
System.out.println("HTTP server started on port " + port);
} catch (IOException e) {
e.printStackTrace();
}
}
public void start() {
while (true) {
try {
Socket clientSocket = serverSocket.accept();
threadPool.execute(new RequestHandler(clientSocket));
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class RequestHandler implements Runnable {
private Socket clientSocket;
public RequestHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
try {
InputStream input = clientSocket.getInputStream();
OutputStream output = clientSocket.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
PrintWriter writer = new PrintWriter(output, true);
// Read request line
String requestLine = reader.readLine();
if (requestLine == null) {
writer.println("HTTP/1.1 400 Bad Request");
return;
}
String[] requestLineParts = requestLine.split(" ");
if (requestLineParts.length != 3) {
writer.println("HTTP/1.1 400 Bad Request");
return;
}
String method = requestLineParts[0];
String path = requestLineParts[1];
String httpVersion = requestLineParts[2];
// Read headers
Map<String, String> headers = new HashMap<>();
String headerLine;
while ((headerLine = reader.readLine()) != null && !headerLine.isEmpty()) {
String[] headerParts = headerLine.split(": ");
if (headerParts.length != 2) {
writer.println("HTTP/1.1 400 Bad Request");
return;
}
headers.put(headerParts[0], headerParts[1]);
}
// Read request body
StringBuilder body = new StringBuilder();
if (headers.containsKey("Content-Length")) {
int contentLength = Integer.parseInt(headers.get("Content-Length"));
if (contentLength > 0) {
char[] buffer = new char[contentLength];
reader.read(buffer, 0, contentLength);
body.append(buffer);
}
}
// Parse cookies
Map<String, String> cookies = new HashMap<>();
if (headers.containsKey("Cookie")) {
String[] cookieParts = headers.get("Cookie").split("; ");
for (String cookiePart : cookieParts) {
String[] cookiePair = cookiePart.split("=");
cookies.put(cookiePair[0], cookiePair[1]);
}
}
// Get session ID from cookies or create a new session
String sessionId;
Session session;
if (cookies.containsKey(SESSION_ID_COOKIE_NAME)) {
sessionId = cookies.get(SESSION_ID_COOKIE_NAME);
session = sessions.get(sessionId);
if (session == null || session.isExpired()) {
session = new Session();
sessions.put(session.getId(), session);
sessionId = session.getId();
writer.println("Set-Cookie: " + SESSION_ID_COOKIE_NAME + "=" + sessionId + "; Path=/; HttpOnly");
} else {
session.updateLastAccessedTime();
}
} else {
session = new Session();
sessions.put(session.getId(), session);
sessionId = session.getId();
writer.println("Set-Cookie: " + SESSION_ID_COOKIE_NAME + "=" + sessionId + "; Path=/; HttpOnly");
}
// Handle request
switch (method) {
case "GET":
handleGetRequest(path, headers, body.toString(), session, writer);
break;
case "HEAD":
handleHeadRequest(path, headers, body.toString(), session, writer);
break;
case "POST":
handlePostRequest(path, headers, body.toString(), session, writer);
break;
default:
writer.println("HTTP/1.1 501 Not Implemented");
}
output.flush();
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void handleGetRequest(String path, Map<String, String> headers, String body, Session session, PrintWriter writer) {
// TODO: handle GET request
}
private void handleHeadRequest(String path, Map<String, String> headers, String body, Session session, PrintWriter writer) {
// TODO: handle HEAD request
}
private void handlePostRequest(String path, Map<String, String> headers, String body, Session session, PrintWriter writer) {
// TODO: handle POST request
}
}
private class Session {
private String id;
private long lastAccessedTime;
public Session() {
id = UUID.randomUUID().toString();
updateLastAccessedTime();
}
public String getId() {
return id;
}
public boolean isExpired() {
return System.currentTimeMillis() - lastAccessedTime > SESSION_TIMEOUT;
}
public void updateLastAccessedTime() {
lastAccessedTime = System.currentTimeMillis();
}
}
public static void main(String[] args) {
int port = args.length > 0 ? Integer.parseInt(args[0]) : DEFAULT_PORT;
HTTPServer server = new HTTPServer(port);
server.start();
}
}
```
HTTP客户端程序:
```java
import java.io.*;
import java.net.*;
import java.util.*;
public class HTTPClient {
private static final String DEFAULT_HOST = "localhost";
private static final int DEFAULT_PORT = 8080;
private static final String USER_AGENT = "Java/1.8";
private String host;
private int port;
public HTTPClient(String host, int port) {
this.host = host;
this.port = port;
}
public HttpResponse sendRequest(HttpRequest request) throws IOException {
Socket socket = new Socket(host, port);
OutputStream output = socket.getOutputStream();
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
PrintWriter writer = new PrintWriter(output, true);
// Write request line
writer.println(request.getMethod() + " " + request.getPath() + " HTTP/1.1");
// Write headers
Map<String, String> headers = request.getHeaders();
headers.put("Host", host + ":" + port);
headers.put("User-Agent", USER_AGENT);
for (String headerName : headers.keySet()) {
writer.println(headerName + ": " + headers.get(headerName));
}
// Write request body
String body = request.getBody();
if (!body.isEmpty()) {
writer.println("Content-Length: " + body.length());
writer.println();
writer.println(body);
} else {
writer.println();
}
// Read response
String statusLine = reader.readLine();
if (statusLine == null) {
throw new IOException("Server closed connection");
}
String[] statusLineParts = statusLine.split(" ");
if (statusLineParts.length != 3) {
throw new IOException("Invalid response status line: " + statusLine);
}
int statusCode = Integer.parseInt(statusLineParts[1]);
Map<String, String> responseHeaders = new HashMap<>();
String headerLine;
while ((headerLine = reader.readLine()) != null && !headerLine.isEmpty()) {
String[] headerParts = headerLine.split(": ");
if (headerParts.length != 2) {
throw new IOException("Invalid response header: " + headerLine);
}
responseHeaders.put(headerParts[0], headerParts[1]);
}
StringBuilder responseBody = new StringBuilder();
int contentLength = responseHeaders.containsKey("Content-Length") ? Integer.parseInt(responseHeaders.get("Content-Length")) : -1;
if (contentLength > 0) {
char[] buffer = new char[contentLength];
reader.read(buffer, 0, contentLength);
responseBody.append(buffer);
}
socket.close();
return new HttpResponse(statusCode, responseHeaders, responseBody.toString());
}
public static void main(String[] args) {
String host = args.length > 0 ? args[0] : DEFAULT_HOST;
int port = args.length > 1 ? Integer.parseInt(args[1]) : DEFAULT_PORT;
HTTPClient client = new HTTPClient(host, port);
try {
// Send GET request
HttpRequest getRequest = new HttpRequest("GET", "/", new HashMap<>(), "");
HttpResponse getResponse = client.sendRequest(getRequest);
System.out.println("GET response:");
System.out.println(getResponse);
// Send POST request
Map<String, String> postHeaders = new HashMap<>();
postHeaders.put("Content-Type", "application/x-www-form-urlencoded");
HttpRequest postRequest = new HttpRequest("POST", "/", postHeaders, "name=John&age=30");
HttpResponse postResponse = client.sendRequest(postRequest);
System.out.println("POST response:");
System.out.println(postResponse);
} catch (IOException e) {
e.printStackTrace();
}
}
}
class HttpRequest {
private String method;
private String path;
private Map<String, String> headers;
private String body;
public HttpRequest(String method, String path, Map<String, String> headers, String body) {
this.method = method;
this.path = path;
this.headers = headers;
this.body = body;
}
public String getMethod() {
return method;
}
public String getPath() {
return path;
}
public Map<String, String> getHeaders() {
return headers;
}
public String getBody() {
return body;
}
}
class HttpResponse {
private int statusCode;
private Map<String, String> headers;
private String body;
public HttpResponse(int statusCode, Map<String, String> headers, String body) {
this.statusCode = statusCode;
this.headers = headers;
this.body = body;
}
public int getStatusCode() {
return statusCode;
}
public Map<String, String> getHeaders() {
return headers;
}
public String getBody() {
return body;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.1 ").append(statusCode).append("\n");
for (String headerName : headers.keySet()) {
sb.append(headerName).append(": ").append(headers.get(headerName)).append("\n");
}
sb.append("\n");
sb.append(body);
return sb.toString();
}
}
```
阅读全文