package com.yc.tomcat;
import java.net.ServerSocket;
import java.net.Socket;
public class MyCatServer {
public static void main(String[] args) {
MyCatServer mcs = new MyCatServer();
mcs.startServer();
}
public void startServer() {
int port = 8080;
boolean flag = false;
try (ServerSocket ss = new ServerSocket(port)) {
while (!flag) {
Socket s = ss.accept();
Thread t = new Thread(new TaskService(s));
t.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.yc.tomcat;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class TaskService implements Runnable {
private Socket socket;
private InputStream in;
private OutputStream out;
private boolean flag;
private String connection = "close";
public TaskService(Socket socket) {
this.socket = socket;
flag = true;
try {
in = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
flag = false;
}
try {
out = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
flag = false;
}
}
@Override
public void run() {
while (flag) {
try {
HttpServletRequest request = new HttpServletRequest(this.in, socket);
HttpServletResponse response = new HttpServletResponse(request, this.out);
} catch (Exception e) {
e.printStackTrace();
} finally {
if ("close".equals(connection)) {
flag = false;
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
}
package com.yc.tomcat;
import java.io.File;
import java.io.InputStream;
import java.net.Socket;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
public class HttpServletRequest {
private InputStream in;
private Socket socket;
private String method;
private String requestURL;
private String requestURI;
private String contextPath;
private String queryString;
private Map<String, String[]> parameterMap = new ConcurrentHashMap<>();
private String scheme;
private String protocol;
private String realPath;
public HttpServletRequest(InputStream in, Socket socket) {
this.in = in;
this.socket = socket;
parseRequest();
}
private void parseRequest() {
String requestInfoString = readFromInpuStream();
if (requestInfoString == null || "".equals(requestInfoString)) {
throw new RuntimeException("读取输入流异常");
}
parseRequestInfoString(requestInfoString);
}
private void parseRequestInfoString(String requestInfoString) {
StringTokenizer st = new StringTokenizer(requestInfoString);
this.method = st.nextToken();
this.requestURI = st.nextToken();
int questionIndex = this.requestURI.indexOf("?");
if (questionIndex >= 0) {
this.queryString = this.requestURI.substring(questionIndex + 1);
this.requestURI = this.requestURI.substring(0, questionIndex);
}
this.protocol = st.nextToken();
this.scheme = this.protocol.substring(0, this.protocol.indexOf("/"));
int slashIndex = this.requestURI.indexOf("/", 1);
if (slashIndex >= 0) {
this.contextPath = this.requestURI.substring(0, slashIndex);
} else {
this.contextPath = this.requestURI;
}
this.requestURL = this.scheme + "://" + this.socket.getRemoteSocketAddress() + ":" + this.requestURI;
if (this.queryString != null && this.queryString.length() > 0) {
String[] ps = this.queryString.split("&");
for (String s : ps) {
String[] params = s.split("=");
this.parameterMap.put(params[0], params[1].split(","));
}
}
this.realPath = System.getProperty("user.dir") + File.separator + "webapps";
}
private String readFromInpuStream() {
String requestInfoString = null;
StringBuffer sb = new StringBuffer(100 * 1024);
int length = -1;
byte[] bs = new byte[100 * 1024];
try {
length = this.in.read(bs);
} catch (Exception e) {
e.printStackTrace();
length = 0;
}
for (int i = 0; i < length; i++) {
sb.append((char) bs[i]);
}
requestInfoString = sb.toString();
return requestInfoString;
}
public Socket getSocket() {
return socket;
}
public String getContextPath() {
return contextPath;
}
public String getRealPath() {
return realPath;
}
public String getMethod() {
return method;
}
public InputStream getIn() {
return in;
}
public String getRequestURL() {
return requestURL;
}
public String getRequestURI() {
return requestURI;
}
public String getQueryString() {
return queryString;
}
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
public String getScheme() {
return scheme;
}
public String getProtocol() {
return protocol;
}
}
package com.yc.tomcat;
import java.io.*;
public class HttpServletResponse {
private HttpServletRequest request;
private OutputStream out;
public HttpServletResponse(HttpServletRequest request, OutputStream out) {
this.request = request;
this.out = out;
outResult();
}
private void outResult() {
byte[] fileContent = null;
String responseProtocol = null;
String uri = this.request.getRequestURI();
String fileName = this.request.getRealPath() + uri;
File file = new File(fileName);
if (file.exists() == false) {
File file404 = new File(this.request.getRealPath(), "404.html");
fileContent = readFile(file404);
responseProtocol = get404Protocol(fileContent);
} else {
fileContent = readFile(file);
responseProtocol = get200Protocol(fileContent);
}
try {
this.out.write(responseProtocol.getBytes());
this.out.flush();
this.out.write(fileContent);
this.out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (this.out != null) {
try {
this.out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private String get200Protocol(byte[] fileContent) {
String uri = this.request.getRequestURI();
int index = uri.lastIndexOf(".");
if (index >= 0) {
index = index + 1;
}
String extension = uri.substring(index);
String pro200 = "";
if ("html".equalsIgnoreCase(extension) || "htm".equalsIgnoreCase(extension)) {
pro200 = "HTTP/1.1 200\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length: " + fileContent.length + "\r\n\r\n";
} else if ("css".equalsIgnoreCase(extension)) {
pro200 = "HTTP/1.1 200\r\n" +
"Content-Type: text/css\r\n" +
"Content-Length: " + fileContent.length + "\r\n\r\n";
} else if ("js".equalsIgnoreCase(extension)) {
pro200 = "HTTP/1.1 200\r\n" +
"Content-Type: text/javascript\r\n" +
"Content-Length: " + fileContent.length + "\r\n\r\n";
} else if ("jpg".equalsIgnoreCase(extension) || "jpeg".equalsIgnoreCase(extension)) {
pro200 = "HTTP/1.1 200\r\n" +
"Content-Type: text/jpeg\r\n" +
"Content-Length: " + fileContent.length + "\r\n\r\n";
}
return pro200;
}
private String get404Protocol(byte[] fileContent) {
String pro404 = "HTTP/1.1 404\r\n" +
"Content-Type: text/html;charset=utf-8\r\n" +
"Content-Language: zh-CN\r\n" +
"Content-Length: " + fileContent.length + "\r\n\r\n";
return pro404;
}
private byte[] readFile(File file) {
FileInputStream fin = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
fin = new FileInputStream(file);
byte[] bs = new byte[10 * 1024];
int length = -1;
while ((length = fin.read(bs, 0, bs.length)) != -1) {
baos.write(bs, 0, length);
baos.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fin != null) {
try {
fin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return baos.toByteArray();
}
}