深入剖析Tomcat讀書筆記(1)——tomcat的連線本質
備註:此書的版本為Tomcat4.0 ,還是原始的BIO連線方式,還沒有看完 ,過不涉及NIO
1 .HTTP請求與響應
請求報文
GET /asd HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
響應
//response header 表示這是遵循http協議的
HTTP/1.1 200 OK
content-type:text/html
//response Body
<h1>Hello asd</h1>
<h2>shutdown_command:/shutdown</h2>
那麼tomcat的作用就是接受請求報文並返回相應的響應報文。實現了這個功能就相當於實現主要功能。
2 . 實現
在學習java的實時通訊的時候我們使用的就是socket(套接字)實現的。開一個SocketServer類接受客戶端請求,並且同時會生成一個socket來處理客戶端的請求。接收到請求之後我們就可以socket的輸出流進行返回報文。若想要瀏覽器識別,就要遵循http協議。
比如我們實現一個在瀏覽器地址輸入127.0.0.1:8080/name 返回報文是 Hello name!
//MyHttpServer.java
package com.wuhulala.chap1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* http伺服器類
*
* @author xueaohui
* @version 1.0
* @date 2017/2/19
*/
public class MyHttpServer {
//地址
private static final String HTTP_HOST = "127.0.0.1";
//埠
private static final int HTTP_PORT = 8080;
//停止伺服器命令
private static final String SHUTDOWN_COMMAND = "/shutdown";
public static void main(String[] args) {
MyHttpServer server = new MyHttpServer();
System.out.println(">>>>>>>>>啟動伺服器ing<<<<<<<<<<");
server.await();
}
private void await() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(HTTP_PORT, 1, InetAddress.getByName(HTTP_HOST));
} catch (IOException e) {
System.out.println(">>>>>>>>>啟動伺服器異常<<<<<<<<<<");
e.printStackTrace();
System.exit(1);
}
System.out.println(">>>>>>>>>啟動伺服器成功<<<<<<<<<<");
boolean shutdown = false;
while(!shutdown){
Socket client = null;
InputStream input = null;
OutputStream out = null;
try {
client = serverSocket.accept();
input = client.getInputStream();
out = client.getOutputStream();
MyRequest request = new MyRequest(input);
request.parse();
MyResponse response = new MyResponse(out);
response.setRequest(request);
response.sendMessage();
client.close();
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
} catch (IOException e) {
System.out.println(">>>>>>>>>關閉Socket異常<<<<<<<<<<");
System.out.println(e.getMessage());
System.out.println(">>>>>>>>>>>>>><<<<<<<<<<<<<<<<<");
}
}
}
}
//
package com.wuhulala.chap1;
import java.io.IOException;
import java.io.InputStream;
/**
* 請求類,用於格式化請求報文
*
* @author xueaohui
* @version 1.0
* @date 2017/2/19
*/
public class MyRequest {
private InputStream input;
private String uri;
public MyRequest(InputStream input) {
this.input = input;
}
/**
* 解析報文
*/
public void parse() {
StringBuffer request = new StringBuffer(2048);
int i = 0;
byte[] buffer = new byte[2048];
try {
i = input.read(buffer);
} catch (IOException e) {
System.out.println(">>>>>>>>>>>>>>解析HTTP協議錯誤<<<<<<<<<<<<<<<");
System.out.println(e.getMessage());
}
for (int j = 0; j < i; j++) {
request.append((char)buffer[j]);
}
System.out.println(">>>>>>>>>>>>>>解析HTTP協議結果<<<<<<<<<<<<<<<");
System.out.println(request.toString());
System.out.println(">>>>>>>>>>>>>>解析HTTP協議結果<<<<<<<<<<<<<<<");
parseURI(request.toString());
}
/**
* 通過請求解析URI
*
* @param request 請求字串
*/
private void parseURI(String request) {
int index1, index2;
index1 = request.indexOf(' ');
if (index1 != -1) {
index2 = request.indexOf(' ', index1 + 1);
if(index2 > index1){
uri = request.substring(index1+1,index2);
}else{
uri = "error";
}
}else{
uri = "error";
}
}
public String getUri() {
return uri;
}
}
package com.wuhulala.chap1;
import java.io.IOException;
import java.io.OutputStream;
/**
* 響應類 用於輸出響應報文
*
* @author xueaohui
* @version 1.0
* @date 2017/2/19
*/
public class MyResponse {
private OutputStream out;
private MyRequest request;
public MyResponse(OutputStream out) {
this.out = out;
}
public void setRequest(MyRequest request) {
this.request = request;
}
public void sendMessage() throws IOException {
String message = "HTTP/1.1 200 OK \r\n" +
"content-type:text/html\r\n" +
"\r\n" +
"<h1>Hello "+request.getUri()+"!</h1>" +
"<h2>shutdown_command:/shutdown</h2>";
out.write(message.getBytes());
}
}
3. 總結
此例通過socket實現接受http請求。解析了tomcat接受請求的原理。那麼我現在聯想到了Tomcat通過NIO連線的本質。。。不知道爾等想到了嗎
相關文章
- tomcat8.5.57原始碼閱讀筆記1Tomcat原始碼筆記
- tomcat深入學習(二)(1) ---- tomcat初始化Tomcat
- Tomcat 的 JDBC 連線池TomcatJDBC
- Tomcat學習筆記Tomcat筆記
- 深入淺出Tomcat/4 - Tomcat容器Tomcat
- 《網路是怎樣連線的》讀書筆記筆記
- 《網路是怎樣連線的》讀書筆記一筆記
- 讀書筆記之《網路是怎樣連線的》筆記
- 深入淺出Tomcat/3 - Tomcat生命週期Tomcat
- 深入淺出node讀書筆記筆記
- 《如何有效閱讀一本書》讀書筆記筆記
- 筆記本怎麼連印表機 筆記本與印表機連線的教程筆記
- 淺讀tomcat架構設計和tomcat啟動過程(1)Tomcat架構
- 深入理解java虛擬機器——讀書筆記1Java虛擬機筆記
- 【讀書筆記】Postgresql連線方法及執行器筆記SQL
- tomcat拒絕連線解決方法Tomcat
- 《C#本質論》讀書筆記<四>值型別再解析C#筆記型別
- 《線性代數的本質》筆記10筆記
- 《線性代數的本質》筆記(09)筆記
- 深入淺出Tomcat/2 - Tomcat啟動和停止Tomcat
- 線性代數的本質課程筆記1-6講筆記
- 《深入核心的敏捷開發》讀書筆記(2)敏捷筆記
- 諾埃爾的讀書筆記1筆記
- 深入淺出Tomcat系列Tomcat
- Tomcat深入淺出(一)Tomcat
- 曹工說Tomcat3:深入理解 Tomcat DigesterTomcat
- 某客戶系統tomcat連線池連線異常Tomcat
- 《線性代數的本質》筆記(04-附註1-05)筆記
- 【Tomcat】Tomcat原始碼閱讀之StandardHost與HostConfig的分析Tomcat原始碼
- 《Google File System》讀書筆記(1)Go筆記
- 讀書筆記-資訊收集1筆記
- 筆記本怎麼新增隱藏wifi 筆記本如何連線隱藏的無線wifi筆記WiFi
- Tomcat深入淺出——Servlet(三)TomcatServlet
- Tomcat深入淺出——Servlet(二)TomcatServlet
- 《線性代數的本質》筆記(01-03)筆記
- 《網路是怎樣連線的》讀書筆記--第一章筆記
- spring boot實戰讀書筆記(1)Spring Boot筆記
- 筆記本怎麼連藍芽耳機 筆記本連線藍芽耳機步驟筆記藍芽
- 深入淺出Tomcat/1- 來歷和配置檔案Tomcat