一、实现基本功能
package net.test.server;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.function.Function;
public class Step1Server {
ServerSocket serverSocket;
Function<String,String> handler;
public Step1Server(Function<String,String> handler){
this.handler = handler;
}
public void listen(int port) throws IOException {
serverSocket = new ServerSocket(port);
while (true){
this.accept();
}
}
public void accept(){
try {
Socket socket = serverSocket.accept();
System.out.println("A socket created");
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream));
StringBuilder requestBuilder = new StringBuilder();
String line = "";
while (true) {
line = bufferedReader.readLine();
if(line == null || line.isEmpty()) {
break;
}
requestBuilder.append(line + '\n');
}
String request = requestBuilder.toString();
System.out.println(request);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String response = this.handler.apply(request);
bufferedWriter.write(response);
bufferedWriter.flush();
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
Step1Server server = new Step1Server(req -> {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "HTTP/1.1 200 ok\n\nGood!\n";
});
server.listen(9999);
}
}
二、使用多线程进行优化
package net.test.server;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.function.Function;
public class Step2Server {
ServerSocket serverSocket;
Function<String,String> handler;
public Step2Server(Function<String,String> handler){
this.handler = handler;
}
public void listen(int port) throws IOException {
serverSocket = new ServerSocket(port);
while (true){
this.accept();
}
}
public void accept() throws IOException {
Socket socket = serverSocket.accept();
new Thread(() -> {
try {
this.handler(socket);
} catch (Exception exception) {
exception.printStackTrace();
}
}).start();
}
public void handler(Socket socket){
try {
System.out.println("A socket created");
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream));
StringBuilder requestBuilder = new StringBuilder();
String line = "";
while (true) {
line = bufferedReader.readLine();
if(line == null || line.isEmpty()) {
break;
}
requestBuilder.append(line + '\n');
}
String request = requestBuilder.toString();
System.out.println(request);
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
String response = this.handler.apply(request);
bufferedWriter.write(response);
bufferedWriter.flush();
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
Step2Server server = new Step2Server(req -> {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "HTTP/1.1 200 ok\n\nGood!\n";
});
server.listen(9999);
}
}
三、进行抽象化
package net.test.server;
import java.io.IOException;
@FunctionalInterface
public interface IHandlerInterface {
void handler(Request request, Response response) throws IOException;
}
package net.test.server;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Request {
static Pattern methodRegex = Pattern.compile("(GET|PUT|POST|DELETE|OPTIONS|TRACE|HEAD)");
public String getBody() {
return body;
}
public String getMethod() {
return method;
}
public HashMap<String, String> getHeaders() {
return headers;
}
private final String body;
private final String method;
private final HashMap<String, String> headers;
public Request(Socket socket) throws IOException {
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream));
String methodLine = bufferedReader.readLine();
Matcher matcher = methodRegex.matcher(methodLine);
matcher.find();
String method = matcher.group();
HashMap<String, String> headMap = new HashMap<>();
String line = "";
while (true) {
line = bufferedReader.readLine();
if (line == null || line.isEmpty()) {
break;
}
String[] split = line.split(":");
if (split.length == 2){
headMap.put(split[0],split[1]);
}else {
headMap.put(split[0], split[1] + ":" + split[2]);
}
}
StringBuilder body = new StringBuilder();
char[] buffer = new char[1024];
while(dataInputStream.available() > 0) {
bufferedReader.read(buffer);
body.append(buffer);
}
this.body = body.toString();
this.method = method;
this.headers = headMap;
}
}
package net.test.server;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.HashMap;
public class Response {
Socket socket;
private int status;
public static volatile HashMap<Integer, String> codeMap;
public Response(Socket socket) {
this.socket = socket;
if(codeMap == null) {
synchronized (Response.class){
if (codeMap == null){
codeMap = new HashMap<>();
codeMap.put(200, "OK");
}
}
}
}
public void send(String msg) throws IOException {
String resp = "HTTP/1.1 " + this.status + " " + codeMap.get(this.status) + "\n";
resp += "\n";
resp += msg;
this.sendRaw(resp);
}
public void sendRaw(String msg) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
bufferedWriter.write(msg);
bufferedWriter.flush();
socket.close();
}
}
package net.test.server;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Step3Server {
ServerSocket serverSocket;
IHandlerInterface httpHandler;
public Step3Server(IHandlerInterface httpHandler){
this.httpHandler = httpHandler;
}
public void listen(int port) throws IOException {
serverSocket = new ServerSocket(port);
while (true){
this.accept();
}
}
public void accept() throws IOException {
Socket socket = serverSocket.accept();
new Thread(()->{
try {
this.handler(socket);
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
private void handler(Socket socket) throws IOException {
Request request = new Request(socket);
Response response = new Response(socket);
this.httpHandler.handler(request, response);
}
public static void main(String[] argv) throws IOException {
Step3Server server = new Step3Server((req, resp) -> {
System.out.println(req.getHeaders());
resp.send("<html><body><h1>Hello world!</h1></body></html>");
});
server.listen(9999);
}
}
|