一、初步理解Tomcat
Tomcat是什么?
Tomcat?是一個開源的?輕量級 Java Web 應用服務器,核心功能是?運行 Servlet/JSP。
Tomcat的核心功能?
Servlet 容器:負責加載、實例化、調用和銷毀 Servlet。
HTTP 服務器:監聽端口(默認 8080),解析 HTTP 請求,封裝 HTTP 響應。
JSP 支持:將 JSP 文件編譯為 Servlet 執行。
線程池管理:并發處理多個請求,提高性能。
二、Servlet的原理
Servlet框架?
三、什么是socket?
Socket(套接字)是計算機網絡中用于進程間通信的核心技術,它允許不同主機或同一主機上的不同程序通過網絡交換數據
?Socket 是什么?
-
定義:Socket 是操作系統提供的抽象接口,本質上是通信的端點(Endpoint)。它封裝了底層網絡協議(如TCP/IP或UDP)的復雜性,提供了一組簡單的API【API(Application Programming Interface,應用程序編程接口)?是軟件系統之間交互的橋梁,定義了如何請求服務、傳遞數據以及返回結果的規則。】供應用程序使用。
-
關鍵要素:
-
IP地址:標識網絡中的主機。
-
端口號:標識主機上的具體服務(如HTTP默認80端口)。
-
協議:如TCP(可靠連接)或UDP(無連接)。
-
端口是邏輯抽象概念,并非物理硬件。
端口是操作系統用來區分不同網絡服務的數字標識(范圍0~65535)。
網卡(硬件)負責收發數據,而端口由操作系統通過協議棧(如TCP/IP)管理。
Socket 是軟件技術,不是物理硬件。
Socket的作用
-
跨網絡通信:使不同設備上的進程能夠交換數據(例如瀏覽器與服務器交互)。
-
支持多種協議:可通過TCP、UDP等協議傳輸數據。
-
雙向通信:建立連接后,雙方可同時發送和接收數據。
-
靈活性:可用于構建各種網絡應用(如Web服務器、聊天軟件、文件傳輸等)。
為什么 Tomcat 需要 Socket??
Tomcat 是一個基于Java的Web服務器和Servlet容器,其核心功能依賴Socket實現:
-
HTTP請求處理:
-
當用戶訪問網站時,瀏覽器通過Socket(TCP連接)向Tomcat發送HTTP請求。
-
Tomcat監聽8080端口(默認),通過Socket接收請求數據,解析后交給Servlet處理。
-
處理完成后,再通過Socket將HTTP響應返回給瀏覽器。
-
-
連接管理:
-
Tomcat使用ServerSocket監聽端口,等待客戶端連接。
-
每收到一個請求,Tomcat會創建一個新的Socket連接(或復用線程池中的連接)處理該請求,實現高并發。
-
-
協議支持:
-
除了HTTP/1.1(基于TCP Socket),Tomcat還支持HTTP/2、WebSocket等,這些協議最終都依賴Socket實現數據傳輸。
-
?Tomcat 中的 Socket 工作流程?
四、Tomcat框架及代碼
網卡上需要注冊端口號。
?通過searchClassUtil類能獲取類的全路徑------>>根據全路徑名生成類對象(反射)------>>獲取類信息
public class HttpServletRequest {private String method;private String url;//............public String getMethod() {return method;}public void setMethod(String method) {this.method = method;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}
}
public class HttpServletResponse {//輸出流private OutputStream outputStream;public HttpServletResponse(OutputStream outputStream){this.outputStream = outputStream;}/*** 返回動態資源* @param context*/public void write(String context) throws IOException {//System.out.println(context);outputStream.write(context.getBytes());}/*** 返回靜態資源*/public void writeHtml(String path) throws Exception {String resourcesPath = FileUtil.getResoucePath(path);File file = new File(resourcesPath);if(file.exists()){//靜態文件存在System.out.println("靜態文件存在");FileUtil.writeFile(file,outputStream);}else {System.out.println("靜態文件不存在");write(ResponseUtil.getResponseHeader404());}}}
/*** tomcat路由*/
public class TomcatRoute {public static HashMap<String, HttpServlet> routes = new HashMap<>();static {List<String> paths = SearchClassUtil.searchClass(); //獲取全路徑名//根據全路徑名稱生成類對象for (String path: paths) {try {Class clazz = Class.forName(path); //生成類對象WDServlet webServlet = (WDServlet) clazz.getDeclaredAnnotation(WDServlet.class);routes.put(webServlet.url(), (HttpServlet) clazz.getDeclaredConstructor().newInstance());} catch (Exception e) {e.printStackTrace();}}}}
public interface servlet {public void service(HttpServletRequest request, HttpServletResponse response) throws IOException;
}
public abstract class HttpServlet implements servlet {public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {}public void doPost(HttpServletRequest request,HttpServletResponse response){}@Overridepublic void service(HttpServletRequest request, HttpServletResponse response) throws IOException {if(request.getMethod().equals("GET")){doGet(request,response);}else if(request.getMethod().equals("POST")){doPost(request,response);}}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface WDServlet {String url() default "";
}
@WDServlet(url = "/myServlet")
public class MyFirstServlet extends HttpServlet {@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) {super.doPost(request, response);}@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {System.out.println("Hello World");response.write(ResponseUtil.getResponseHeader200("hello world hhhhh"));}
}
@WDServlet(url = "/insert")
public class InsertServlet extends HttpServlet {@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {System.out.println("我是insert......");}@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) {super.doPost(request, response);}
}
@WDServlet(url = "/delete")
public class DeleteServlet extends HttpServlet {@Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) {super.doPost(request, response);}@Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {super.doGet(request, response);}
}
/*** tomcat主啟動類*/
public class MyTomcat {static HashMap<String, HttpServlet> routes = TomcatRoute.routes; //tomcat路由\/*** 分發器*/public void dispatch(HttpServletRequest request ,HttpServletResponse response) throws IOException {HttpServlet servlet = routes.get(request.getUrl()); //if(servlet!=null){ //說明請求的就是我們的servletservlet.service(request,response);}}/*** socket 啟動* @throws IOException*/public void start() throws IOException {ServerSocket serverSocket = new ServerSocket(4700); //1.指定監聽的端口號//2.對端口進行監聽while (true){Socket socket = serverSocket.accept();//阻塞監聽//3.打開輸入流,解析客戶端發來的內容InputStream inputStream = socket.getInputStream(); //輸入流HttpServletRequest request = new HttpServletRequest();BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); //將字節流轉換成字符流String str = reader.readLine();request.setMethod(str.split("\\s")[0]);request.setUrl(str.split("\\s")[1]);//4.打開輸出流OutputStream outputStream = socket.getOutputStream();HttpServletResponse response = new HttpServletResponse(outputStream);dispatch(request,response);}}//socketpublic static void main(String[] args) throws IOException {MyTomcat myTomcat = new MyTomcat();myTomcat.start();}
}
?
?五、字節流、字符流
字節流:二進制;
字符流:各種字符
?
?
?
?