学习过tomat源码的人是否有尝试着手写一个简易版的tomcat的冲动呢?其实熟读了tomcat源码的人就应该知道tomcat只是一个强大的socket服务,废话不多说,下面直接贴代码;
一、启动socket监听
public class MyServer {
public static void main(String[] args) throws IOException {
// 服务端创建一个监听
ServerSocket serverSocket = new ServerSocket(9000);
while(true) {
// 监听客户端连接,这里我们暂时没有多线程
Socket socket = serverSocket.accept();
// 要想获取客户端发送过来的内容,就要得到 InputStream类 的输入流对象
InputStream inputStream = socket.getInputStream();
//==========使用我们自定义的http处理的相关类===========//
Request request = new Request(inputStream);
System.out.println(request.readHtml());
// 要想给客户端发送数据,就要得到
OutputStream outputStream = socket.getOutputStream();
Response response = new Response(outputStream);
response.writeHtml("this is server");
// 关闭
inputStream.close();
outputStream.close();
socket.close();
}
}
}
二、将socket的inputStream封装成Request
public class Request {
// 用来保存输入流对象
private InputStream inputStream;
// 从输入流中每次读取的字节长度
private int bufferLength = 1024;
/**
* 构造函数
* @param inputStream 输入流对象
*/
public Request(InputStream inputStream){
this.inputStream = inputStream;
}
/**
* 读取内容
* @return 返回的是字符串
* @throws IOException
*/
public String readHtml() throws IOException {
// 使用BufferedInputStream对象来读取
BufferedInputStream bufferedInputStream = new BufferedInputStream(this.inputStream);
// 每次读取1024字节
byte[] buffer = new byte[this.bufferLength];
// 字符串拼接对象
StringBuilder stringBuilder = new StringBuilder();
int length = 0;
while (true){
length = bufferedInputStream.read(buffer);
// 把读取的字节转为String类型
// 然后拼接成一个大的字符串
stringBuilder.append(new String(buffer,0,length));
if (length<=0 || length<this.bufferLength){
break; // 如果没有读取到内容就跳出循环
}
}
// 返回字符串内容
return stringBuilder.toString();
}
}
三、将socket的outputStream封装成Response
http的响应数据格式必须遵守http协议
public class Response {
private OutputStream outputStream;
public Response(OutputStream outputStream){
this.outputStream = outputStream;
}
public void writeHtml(String html) throws IOException{
// 拼装http响应的数据格式
html = "http/1.1 200 ok\n"
+"\n\n"
+html;
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(this.outputStream);
bufferedOutputStream.write(html.getBytes());
bufferedOutputStream.close();
}
}
四、顺便了普及一下http协议
<1>请求头格式
<2>响应报文格式
<3>状态码说明
100~199:表示成功接收请求,要求客户端继续提交下一次请求才能完成整个处理过程。
200~299:表示成功接收请求并已完成整个处理过程。常用200
300~399:为完成请求,客户需进一步细化请求。例如:请求的资源已经移动一个新地址、常用302(意味着你请求我,我让你去找别人),307和304(我不给你这个资源,自己拿缓存)
400~499:客户端的请求有错误,常用404(意味着你请求的资源在web服务器中没有)403(服务器拒绝访问,权限不够)
500~599:服务器端出现错误,常用500
http协议参考资料:https://blog.csdn.net/shouwang666666/article/details/70232053
五、浏览器通过http协议访问服务并返回结果
在浏览器中输入:http://127.0.0.1:9000/
控制台打印请求数据格式
参考资料:https://blog.csdn.net/github_26672553/article/details/77507797