【0】README

0.1)本文部分描述转自“深入剖析tomcat”, 旨在学习  一个简单的web server  的基础知识;

0.2)for complete source code, please visit https://github.com/pacosonTang/HowTomcatWorks/tree/master/chapter1

【1】HTTP

【1.1】HTTP请求
1)一个HTTP请求包括以下3部分(parts):(干货——一个HTTP请求包括以下3部分(parts))
p1)请求方法——统一资源标识符(URI)——协议/版本;
p2)请求头;
p3)实体;
2)HTTP 请求的示例如下所示:(干货——HTTP请求代码荔枝)
Post /examples/default.jsp HTTP/1.1
Accept: text/plain; text/html
Accept-Language: en-gb
Connection: Keep-Alive
Host: localhost
User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
Content-Length: 33
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
// 这里是空行(CRLF)
lastName=Yun&firstName=Lin
对以上HTTP请求的分析(Analysis):(干货——对HTTP请求的分析)
A1)第一行:请求方法——URI——协议/版本(Post /examples/default.jsp HTTP/1.1)
A2)HTTP1.1 支持的请求方法有:GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE;
A3)URI:指定internet 资源的完整路径;而统一资源定位符(URL) 是 URI 的一种类型;
A4)在请求头和请求实体间有一个空行:该空行只有 CRLF 符;CRLF 告诉HTTP 服务器请求实体正文从哪里开始;正文(lastName=Yun&firstName=Lin)

【1.2】HTTP响应
1)HTTP响应也包括3部分(parts):
part1)协议——状态码——描述;
part2)响应头;
part3)响应实体段;
2)HTTP响应的荔枝,如下所示:
HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Date: Mon, 5 Jan 2004 13:13:33 GMT
Content-Type: text/html
Last-Modified: Mon, 5 Jan 2004 13:13:12 GMT
Content-Length: 112
//空行(CRLF)
<html>
<head>
<title>hello, world</title>
</head>
<body>
hello, world
</body>
</html>
对上述HTTP响应代码的分析(Analysis):
A1)第一行的200,表示状态码(请求发送成功);
A2)响应头和响应实体正文间由只包含 CRLF 的一个空行分隔;
【1.3】Socket类
1)看个荔枝:(创建一个套接字,用于与本地HTTP Server 进行通信(127.0.0.1 表示一个本地主机),发送HTTP请求接收server 的响应信息);
// 创建一个套接字,用于与本地HTTP Server 进行通信(127.0.0.1 表示一个本地主机),发送HTTP请求接收server 的响应信息
// 采用tomcat 开启8080 端口
public class SocketTest {public static void main(String[] args) throws Exception {try(Socket socket = new Socket("127.0.0.1", 8080)){OutputStream os = socket.getOutputStream();boolean autoflush = true;PrintWriter out = new PrintWriter(socket.getOutputStream(), autoflush);BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));// send an HTTP request to the web serverout.println("GET /index.jsp HTTP/1.1");out.println("Host: localhost:8080");out.println("Connection: Close");out.println();// read the responseboolean loop = true;StringBuffer sb = new StringBuffer(8096);while(loop) {if(in.ready()) {int i = 0;while(i != -1) {i = in.read();sb.append((char)i);}loop = false;}Thread.currentThread().sleep(50);}// display the response to the out consoleSystem.out.println(sb.toString());socket.close();}}
}
【3】应用程序
0)intro:web服务器应用程序包括3个类: HttpServer, Request, Response;
1)我们先看运行结果(显然发出了两个HTTP 请求,浏览器发出一个获取静态资源的 HTTP请求, 而该静态资源又 发出获取图像资源的 HTTP 请求)(干货——显然发出了两个HTTP 请求):
E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src>java com.tomcat.chapter1.HttpServer
E:\bench-cluster\cloud-data-preprocess\HowTomcatWorks\src
GET /index.html HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6GET /images/psu.jpg HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Accept: image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
Referer: http://localhost:8080/index.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6GET /SHUTDOWN HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6

2)HttpServer, Request, Response 的源码如下所示:
public class HttpServer { // 接受HTTP 请求的web server/** WEB_ROOT is the directory where our HTML and other files reside.*  For this package, WEB_ROOT is the "webroot" directory under the working*  directory.*  The working directory is the location in the file system*  from where the java command was invoked.*/public static final String WEB_ROOT =System.getProperty("user.dir") + File.separator  + "webroot";// shutdown commandprivate static final String SHUTDOWN_COMMAND = "/SHUTDOWN";// the shutdown command receivedprivate boolean shutdown = false;public static void main(String[] args) {System.out.println(System.getProperty("user.dir"));HttpServer server = new HttpServer();server.await();// 会在指定端口上等待HTTP请求。}public void await() {ServerSocket serverSocket = null;int port = 8080;try {serverSocket =  new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));}catch (IOException e) {e.printStackTrace();System.exit(1);}// Loop waiting for a requestwhile (!shutdown) {Socket socket = null;InputStream input = null;OutputStream output = null;try {socket = serverSocket.accept();input = socket.getInputStream();output = socket.getOutputStream();// create Request object and parse,创建 HTTP请求对象Request request = new Request(input);request.parse(); // 解析HTTP请求字符串// create Response object,创建HTTP 响应对象Response response = new Response(output);response.setRequest(request);response.sendStaticResource(); // 发送静态资源到client// Close the socketsocket.close();//check if the previous URI is a shutdown commandshutdown = request.getUri().equals(SHUTDOWN_COMMAND);}catch (Exception e) {e.printStackTrace();continue;}}}
}
public class Request { // 封装 HTTP 请求字符串的类private InputStream input;private String uri;public Request(InputStream input) {this.input = input;}public void parse() {// Read a set of characters from the socketStringBuffer request = new StringBuffer(2048);int i;byte[] buffer = new byte[2048];try {i = input.read(buffer);}catch (IOException e) {e.printStackTrace();i = -1;}for (int j=0; j<i; j++) {request.append((char) buffer[j]);}System.out.print(request.toString());uri = parseUri(request.toString());}private String parseUri(String requestString) {int index1, index2;index1 = requestString.indexOf(' ');if (index1 != -1) {index2 = requestString.indexOf(' ', index1 + 1);if (index2 > index1)return requestString.substring(index1 + 1, index2);}return null;}public String getUri() {return uri;}}
public class Response {  <span style="font-family: 宋体;">// 封装 HTTP 响应字符串的类</span>private static final int BUFFER_SIZE = 1024;Request request;OutputStream output;public Response(OutputStream output) {this.output = output;}public void setRequest(Request request) {this.request = request;}public void sendStaticResource() throws IOException {byte[] bytes = new byte[BUFFER_SIZE];FileInputStream fis = null;try {File file = new File(HttpServer.WEB_ROOT, request.getUri());if (file.exists()) {fis = new FileInputStream(file);int ch = fis.read(bytes, 0, BUFFER_SIZE);while (ch!=-1) {output.write(bytes, 0, ch);ch = fis.read(bytes, 0, BUFFER_SIZE);}}else {// file not foundString errorMessage = "HTTP/1.1 404 File Not Found\r\n" +"Content-Type: text/html\r\n" +"Content-Length: 23\r\n" +"\r\n" +"<h1>File Not Found</h1>";output.write(errorMessage.getBytes());}}catch (Exception e) {// thrown if cannot instantiate a File objectSystem.out.println(e.toString() );}finally {if (fis!=null)fis.close();}}
}
补充)本文总结了一张上述应用程序的调用流程图
对上图的分析(Analysis):
A1)HttpServer:
step1)创建服务器套接字,等待接收 client 发出HTTP 连接请求;
step2)连接成功后,利用套接字创建输入输出流;
step3)创建Request对象, 向Request构造函数传入输入流,并利用request实例对象解析  HTTP  请求;
step4)创建Response对象,向Response构造函数传入输出流,且设置 Response中的request变量引用,调用response对象的sendStaticResource方法发送静态资源到 client;
A2)Request:HTTP请求对象,其parse方法用于读取HTTP请求头;其parseUri方法用于解析client 请求的 uri;
A3)Response:HTTP响应对象,其sendStaticResource方法 读取request解析出的uri对应的资源文件,并发送该文件数据到client端;

3)静态资源html

<html>
<head>
<title>How Tomcat Works</title>
</head>
<body>
<img src="./images/psu.jpg">
<br>
hello, my name is xiao tangtang.
</body>
</html>
4)最后po 出 整体的文件目录架构

tomcat(1)一个简单的web server相关推荐

  1. 如何用socket构建一个简单的Web Server

    2019独角兽企业重金招聘Python工程师标准>>> 背景 现代社会网络应用随处可见,不管我们是在浏览网页.发送电子邮件还是在线游戏都离不开网络应用程序,网络编程正在变得越来越重要 ...

  2. python建立一个简单的server_使用Python创建一个简易的Web Server

    Python 2.x中自带了SimpleHTTPServer模块,到Python3.x中,该模块被合并到了http.server模块中.使用该模块,可以快速创建一个简易的Web服务器. 我们在C:\U ...

  3. IDEA 开发一个简单的 web service 项目,并打包部署到 Tomcat

    文章目录 实现的效果 一.创建 web service 项目 二.测试类运行 web service 服务端 三.IDEA 打包 web service 项目 四.web service 项目部署到 ...

  4. java实现web服务器_Java 实现一个简单的web服务器

    在日常的开发中,我们用过很多开源的web服务器,例如tomcat.apache等等.现在我们自己实现一个简单的web服务器,基本的功能就是用户点击要访问的资源,服务器将资源发送到客户端的浏览器.web ...

  5. ipad php mysql_如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1

    原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个i ...

  6. [译]使用 Rust 开发一个简单的 Web 应用,第 4 部分 —— CLI 选项解析

    原文地址:A Simple Web App in Rust, Part 4 -- CLI Option Parsing 原文作者:Joel's Journal 译文出自:掘金翻译计划 本文永久链接:g ...

  7. maven学习笔记之IDEA+Maven+Jetty运行一个简单的web项目

    maven学习笔记 一.什么是maven Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Life ...

  8. ios php mysql实例_如何用PHP/MySQL为 iOS App 写一个简单的web服务器(译) PART1

    原文:http://www.raywenderlich.com/2941/how-to-write-a-simple-phpmysql-web-service-for-an-ios-app 作为一个i ...

  9. web服务器python_一个简单的web服务器(python)

    今天用python写一个简单的web服务器代码网上都有只是为了方便大家学习做了一个简单的教程 第一首先我们来一张架构以及运行过程的流程图 本文学习仅供参考,需要更多资料可以加群:496257369 简 ...

最新文章

  1. Adaboost 算法的原理与推导
  2. Spark 2.4 standalone 部署
  3. Shiro快速入门 —— 9.freemaker使用shiro标签
  4. Py之Xlrd:Xlrd的使用方法总结(获取的sheet名字/sheet索引/sheet内容/数和列数、获取整行和整列的值(列表) 、指定单元格的内容/数据类型)之详细攻略
  5. boost::fusion::for_each用法的测试程序
  6. 网络协议-网络分层、TCP/UDP、TCP三次握手和四次挥手
  7. 用云闪付乘坐公交地铁,能否享受到优惠,取决于这一点
  8. Java进程占用CPU资源过多分析
  9. javafx性能_对JavaFX Mobile应用程序进行性能分析
  10. SQL PROMPT5.3.4.1的一些设置选项
  11. 亚马逊云科技张文翊:引领企业可持续发展的绿色云端之旅
  12. kmeans及模型评估指标_聚类分析的过程和两个常用的聚类算法
  13. Hadoop step by step _ install and configuration environment
  14. 输入法影响JDK字体?
  15. 华硕aura完全卸载_AURA神光同步是什么意思?AURA SYNC神光同步教程
  16. 协调器掉线,路由和终端节点的不同表现
  17. 研发流程——变更流程管控
  18. Adobe的后期摄影图片处理软件Photoshop Lightroom(Lr) 6.2版本下载与安装教程
  19. ios swift MVVM实例(Model-View-ViewModel)
  20. 优化巨量关键词的匹配(转载笔记)

热门文章

  1. [ARC074C] RGB Sequence(dp)
  2. 业界萌新对斯坦纳树的小结
  3. CF1458B Glass Half Spilled
  4. cf570 D. Tree Requests
  5. CF 1529B. Sifid and Strange Subsequences
  6. [ZJOI2010]网络扩容[网络流24题]
  7. 欢乐纪中某B组赛【2019.1.21】
  8. ssl1333-地鼠的困境【二分图,最大匹配,图论】
  9. 【线段树】蝴蝶与花(P6859)
  10. 【AC自动机】单词(luogu 3966/ybtoj AC自动机-2)