手写一个Web服务器,极简版Tomcat
网络传输是通过遵守HTTP协议的数据格式来传输的。
HTTP协议是由标准化组织W3C(World Wide Web Consortium,万维网联盟)和IETF(Internet Engineering Task Force,国际互联网工程任务组)推动和制定的,最后形成RFC文档 [RFC1945](HTTP/1.0)和RFC2616[HTTP/1.1]
可以响应HTTP请求的程序就是Web Server,实现方法并没有统一规范,可以说HTTP协议就是Web Server和网络传输数据之间的接口规范。以后我们会看到,Web Server和处理程序之间的规范是CGI。
一些常见的Web Server有Apache、Nginx、Microsoft IIS、Google GWS。
我们这里手写一个Web Server。
首先我们需要接收网络的请求,根据OSI七层模型,网络的实现是分层的。Web Server属于应用层,要调用下一层(传输层,TCP/IP)的接口,来得到对方发来的网络请求,这个接口就叫做Socket。《计算机网络:自顶向下方法》中写到:“Socket是同一台主机内应用层与传输层之间的接口。因为Socket是建立网络应用程序的可编程接口,所以Socket也被称为应用程序和网络之间的API”。
一、最简单的Web Server
要编写一个Web Server,我们调用系统Socket接口,监听8180端口上收到的网络数据,打印到控制台,并给出一个符合http标准的响应,代码如下:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
public class Server {
public static void main(String[] args) {
Server server = new Server();
server.start();
}
public void start() {
try {
ServerSocket serverSocket = new ServerSocket(8180); // 调用系统socket接口,监听某端口的socket请求
Socket httpInputSocket = serverSocket.accept(); // 在这里,程序线程等待socket输入
this.printHttpRequest(httpInputSocket);
this.responseHttpRequest(httpInputSocket);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 打印来自外部的http请求
*
* @param httpInputSocket
*/
private void printHttpRequest(Socket httpInputSocket) {
try {
// 调用系统IO,打印请求
BufferedReader br = new BufferedReader(new InputStreamReader(httpInputSocket.getInputStream()));
StringBuilder receivedHttp = new StringBuilder();
String line = null;
while ( !"".equals(line = br.readLine())) {
receivedHttp.append(line);
receivedHttp.append(System.getProperty("line.searator", "\n"));
}
System.out.println(receivedHttp.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 返回页面供请求方显示
*
* @param httpInputSocket
*/
private void responseHttpRequest(Socket httpInputSocket) {
// 创建响应体
StringBuilder contextText = new StringBuilder();
contextText.append(
"<html>" +
"<head>" +
"<title>Build A Web Server</title>" +
"</head>" +
"<body>Hello World, This is my page</body>" +
"</html>");
// 创建响应头
StringBuilder headText = new StringBuilder();
headText.append("HTTP/1.1").append(" ").append("200").append(" ").append("OK").append("\n");
headText.append("Server:myServer").append(" ").append("0.0.1v").append(" ");
headText.append("Date:Sat,"+" ").append(new Date()).append("\n");
headText.append("Content-Type:text/html;charset=UTF-8").append("\n");
headText.append("Content-Length:").append(contextText.toString().getBytes().length).append("\n");
// http response
StringBuilder responseText = new StringBuilder();
responseText.append(headText).append("\n").append(contextText);
System.out.println(responseText);
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new OutputStreamWriter(httpInputSocket.getOutputStream()));
bw.write(responseText.toString());
bw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
至此,一个100行不到的Web Server就写好了,运行一下,在浏览器里访问:http://localhost:8180/,可以看到结果:
程序控制台也正确打印:
这个Web Server会对请求到8180端口的所有请求都返回同样的页面,比如我们访问http://localhost:8180/really?foo=123,结果也是一样的:
从这个例子可以看出,通过HTTP请求进行访问,可以不用创建socket客户端。
注意printHttpRequest和responseHttpRequest都要调用才能显示效果,就是说先执行socket 输入流的读取,然后再执行socket输出流输出
手写一个Web服务器,极简版Tomcat的更多相关文章
- Tomcat源码分析 (一)----- 手写一个web服务器
作为后端开发人员,在实际的工作中我们会非常高频地使用到web服务器.而tomcat作为web服务器领域中举足轻重的一个web框架,又是不能不学习和了解的. tomcat其实是一个web框架,那么其内部 ...
- 用C写一个web服务器(二) I/O多路复用之epoll
.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...
- 使用node.js 文档里的方法写一个web服务器
刚刚看了node.js文档里的一个小例子,就是用 node.js 写一个web服务器的小例子 上代码 (*^▽^*) //helloworld.js// 使用node.js写一个服务器 const h ...
- 使用Node.js原生API写一个web服务器
Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...
- wsgiref手写一个web服务端
''' 通过wsgiref写一个web服务端先讲讲wsgiref吧,基于网络通信其根本就是基于socket,所以wsgiref同样也是通过对socket进行封装,避免写过多的代码,将一系列的操作封装成 ...
- 用java写一个web服务器
一.超文本传输协议 Web服务器和浏览器通过HTTP协议在Internet上发送和接收消息.HTTP协议是一种请求-应答式的协议——客户端发送一个请求,服务器返回该请求的应答.HTTP协议使用可靠的T ...
- 【教程】手写简易web服务器
package com.littlepage.testjdbc; import java.io.BufferedReader; import java.io.FileReader; import ja ...
- 手写简易WEB服务器
今天我们来写一个类似于Tomcat的简易服务器.可供大家深入理解一下tomcat的工作原理,本文仅供新手参考,请各位大神指正!首先我们要准备的知识是: Socket编程 HTML HTTP协议 服务器 ...
- 用C写一个web服务器(一) 基础功能
.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...
随机推荐
- 第九章 nginx基础之搭建小游戏
一.nginx部署 1.epel源安装 [root@web01 ~]# yum install -y nginx 2.官方源安装 1.配置官方源[root@web02 ~]# vim /etc/yum ...
- 【Azure媒体服务 Azure Media Service】Azure Media Service中Stream Endpoint 说明 (流式处理终结点)
Azure 媒体服务是一个基于云的媒体工作流平台,用于生成需要编码.打包.内容保护和直播活动广播的解决方案. 在视频的直播,点播方案中,媒体服务的架构主要由三部分构成: 推流端,把本地视频或直播内容推 ...
- B站弹幕爬取
B站弹幕爬取 单个视频弹幕的爬取 B站弹幕都是以xml文件的形式存在的,而xml文件的请求地址是如下形式: http://comment.bilibili.com/233182992.xml ...
- 一个鲜为人知但很实用的Windows使用技巧
作为一个电脑党,最无法忍受的就是每次开机都要手动打开那些必要的程序.有没办法让这些程序自动打开呢?今天小编意外地得到了一个方法,现在分享给大家. (以腾讯桌面整理为例) 1,Win + R 2,输入t ...
- TCMalloc 内存分配原理简析
一.TCMalloc TCMalloc简介 为啥要介绍 TCMalloc? 因为golang的内存分配算法绝大部分都是来自 TCMalloc,golang只改动了其中的一小部分.所以要理解golang ...
- mock.js 学习
安装 npm install mockjs 使用 // 引入 import Mock from 'mockjs' Mock.setup({ timeout: '200 - 400' }) const ...
- Jenkins配置,tomacat版本输出乱码和页面打开报404的问题
1.打开tomact下的startup.bat,tomcat版本控制台中文输出乱码,解决方法是去tomacat安装路径下的conf目录,打开logging.properties文件,将java.uti ...
- java关键字之super
1.在子类的构造方法的第一条语句处调用其父类的构造方法: 如果父类提供了构造方法,并且父类不拥有无参构造方法,则要求子类拥有相同结构的构造方法.即,子类构造方法的参数个数和类型必须和父类的构造方法一致 ...
- Java技术平台介绍
Java的名字的来源:Java是印度尼西亚爪哇岛的英文名称,因盛产咖啡而闻名.Java语言中的许多库类名称,多与咖啡有关, 如JavaBeans(咖啡豆).NetBeans(网络豆)以及ObjectB ...
- STM32入门系列-GPIO工作模式及LED电路原理
GPIO工作模式 由于GPIO内部的结构关系,决定了GPIO可配置成以下几种模式. 输入模式 在输入模式时,施密特触发器打开,输出被禁止.可通过输入数据寄存器GPIOx_IDR读取I/O状态.输入模式 ...