网络传输是通过遵守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的更多相关文章

  1. Tomcat源码分析 (一)----- 手写一个web服务器

    作为后端开发人员,在实际的工作中我们会非常高频地使用到web服务器.而tomcat作为web服务器领域中举足轻重的一个web框架,又是不能不学习和了解的. tomcat其实是一个web框架,那么其内部 ...

  2. 用C写一个web服务器(二) I/O多路复用之epoll

    .container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...

  3. 使用node.js 文档里的方法写一个web服务器

    刚刚看了node.js文档里的一个小例子,就是用 node.js 写一个web服务器的小例子 上代码 (*^▽^*) //helloworld.js// 使用node.js写一个服务器 const h ...

  4. 使用Node.js原生API写一个web服务器

    Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...

  5. wsgiref手写一个web服务端

    ''' 通过wsgiref写一个web服务端先讲讲wsgiref吧,基于网络通信其根本就是基于socket,所以wsgiref同样也是通过对socket进行封装,避免写过多的代码,将一系列的操作封装成 ...

  6. 用java写一个web服务器

    一.超文本传输协议 Web服务器和浏览器通过HTTP协议在Internet上发送和接收消息.HTTP协议是一种请求-应答式的协议——客户端发送一个请求,服务器返回该请求的应答.HTTP协议使用可靠的T ...

  7. 【教程】手写简易web服务器

    package com.littlepage.testjdbc; import java.io.BufferedReader; import java.io.FileReader; import ja ...

  8. 手写简易WEB服务器

    今天我们来写一个类似于Tomcat的简易服务器.可供大家深入理解一下tomcat的工作原理,本文仅供新手参考,请各位大神指正!首先我们要准备的知识是: Socket编程 HTML HTTP协议 服务器 ...

  9. 用C写一个web服务器(一) 基础功能

    .container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...

随机推荐

  1. Flask之WTF

    Flask-WTF是什么? 是一个关于表单的扩展库,可以自动生成表单的HTML代码和验证提交的表单数据,并且提供跨站请求伪造(Cross-Site Request Forgery)保护的功能,使用非常 ...

  2. day70:Vue:Git&路飞学城页面效果

    目录 1.Git 2.路飞学城项目页面效果 0.安装elements UI 1.顶部导航栏效果 2.轮播图效果 1.Git 什么是git?分布式版本管理工具 1.git操作 # 1 创建git本地仓库 ...

  3. 多态(polymorphism)

    2020-10-17        longzqa@163.com        stronglzq [摘要]针对多态及相关知识进行阐述.继承关系中,多个子类都需要调用一个父类抽象方法,使用多态写法: ...

  4. Activity去掉标题不成功的解决方法

    在设置Activity去掉标题的时候遇到的问题,记录一下. 一般会有以下两种方式: 1.Activity中设置 this.requestWindowFeature(Window.FEATURE_NO_ ...

  5. codeforces#426(div1) B - The Bakery (线段树 + dp)

    B. The Bakery   Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought req ...

  6. 雨露均沾的OkHttp—WebSocket长连接的使用&源码解析

    前言 最近老板又来新需求了,要做一个物联网相关的app,其中有个需求是客户端需要收发服务器不定期发出的消息. 内心OS:

  7. java刷题时常用容器详解

    当初学java时,只是简单的把java基础知识过了一遍就跑去刷题了,很多知识都是在刷题的过程中慢慢加深理解的. 由于每次刷题时,刷到与容器有关的我基本上都跑去百度了,例如百度一下:java中List的 ...

  8. mysql 必会基础3

    1.limit [偏移量,0表示没偏移,在第一行:1表示偏移一行,在第二行:默认值为0] 需要展现的记录数 分页的应用: int curPage = 2; int pageSize = 10; int ...

  9. 学会Git玩转GitHub(第二篇) 入门详解 - 精简归纳

    学会Git玩转GitHub(第二篇) 入门详解 - 精简归纳 JERRY_Z. ~ 2020 / 10 / 25 转载请注明出处!️ 目录 学会Git玩转GitHub(第二篇) 入门详解 - 精简归纳 ...

  10. 女朋友看了我的博客,说太LOW了,于是我搞了一天~

    持续原创输出,点击上方蓝字关注我 原创博客+1,点击左下角阅读原文进入 目录 前言 如何下载? 配置文件的分类 基本信息配置 修改主题 Next主题样式设置 添加动态背景 修改链接的样式 添加文章搜索 ...