最简单的web服务器实现(一)(r4笔记第68天)
时间:2022-05-04
本文章向大家介绍最简单的web服务器实现(一)(r4笔记第68天),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
tomcat作为web服务器,想必大家做过web开发的都离不开tomcat了,值得庆幸的是tomcat也是开放源代码的,最近准备好好琢磨琢磨tomcat的源码,还没开始就已经感觉到不少的未知恐惧了,慢慢来把。 可能我的学习方式比较急功近利,但是这种方式收效也快,自己记得在<<Java程序员 上班那点事儿>>里作者写过一个最简单的web服务器实现,自己在网上也比较了一下其它的版本,还是感觉那本书里的版本比较好,在此分享出来,因为时间紧,照着书敲了一遍代码,竟然发现里面有一些很细小的错误,自己准备在这个基础上好好改进一把。 首先来看看web服务器的一些基本原理,我们的实验是基于socket的,开放了一个指定的端口,然后会启用对应的线程来处理浏览器中的请求。如果文件不存在,会报出404错误,否则会解析文件的内容。 HttpServer类是后台服务类,会开放对应的端口和socket来处理浏览发出的请求。 HttpThread类是接受浏览器发送请求的类,通过Receive和Answer来接受和处理浏览器发送的请求,然后返回到客户端中。
package new_test;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class HttpServer {
public static String ROOT="./wwwroot";
public static String defaultPage="index.html";
public static void main(String[] args) throws IOException{
ServerSocket ss = new ServerSocket(8080);
while(true){
Socket s=ss.accept();
System.out.println("Accept Connection...:");
new HttpThread(s).start();
}
}
}
package new_test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import
} java.net.Socket;
public class HttpThread extends Thread {
private Socket socket;
public HttpThread(Socket s) {
this.socket = s;
public void run() {
InputStream ins = null;
OutputStream ous = null;
try {
ous = socket.getOutputStream();
ins = socket.getInputStream();
Receive rcv = new Receive(ins);
String sURL = rcv.parse();
System.out.println("sURL is " + sURL);
if (sURL.equals("/")) {
sURL = HttpServer.defaultPage;
}
Answer ans = new Answer(ous);
ans.send(sURL);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (ins != null) {
ins.close();
}
if (ous != null) {
ous.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package new_test;
import java.io.IOException;
import java.io.InputStream;
public class Receive {
InputStream in = null;
public Receive(InputStream ins) {
this.in = ins;
}
public String parse() {
StringBuffer receiveStr = new StringBuffer(2048);
int i ;
byte[] buffer = new byte[2048];
try {
i = in.read(buffer);
} catch (IOException e) {
i = -1;
}
for (int j = 0; j < i; j++) {
receiveStr.append((char)buffer[j]);
}
return getUri(receiveStr.toString());
}
private String getUri(String receiveStr) {
int index1, index2;
System.out.println("receiveStr is " + receiveStr);
index1 = receiveStr.indexOf(" ");
if (index1 != -1) {
index2 = receiveStr.indexOf(" ", index1 + 1);
if (index2 > index1) {
return receiveStr.substring(index1 + 1, index2);
}
}
return null;
}
}
package new_test;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Answer {
OutputStream out = null;
public Answer(OutputStream ous) {
this.out = ous;
}
public void send(String pageFile) {
byte[] bytes = new byte[2048];
FileInputStream fis = null;
try {
File file = new File(HttpServer.ROOT, pageFile);
if (file.exists()) {
fis = new FileInputStream(file);
int ch = fis.read(bytes, 0, 2048);
String sBody = new String(bytes, 0);
String sendMessage = "HTTP/1.1 200 OKrn"
+ "Content-Type:text/htmlrn" + "Content-Length:" + ch
+ "rn" + "rn" + sBody;
out.write(sendMessage.getBytes());
} else {
String errorMessage = "Http/1.1 404 File NOT FOUNDrn"
+ "Content-Type:text/htmlrn"
+ "Content-Length:23rn" + "rn"
+ "<h1>File Not Found</h1>";
out.write(errorMessage.getBytes());
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
一个简单调用的情况就是,如果不存在对应的页面会直接抛出File Not Found的错误信息
- 分布式文件存储的数据库开源项目MongoDB
- 使用 JavaScriptService 在.NET Core 里实现DES加密算法
- 拒绝全英文垃圾评论!仅用代码实现
- 在.NET Core 里使用 BouncyCastle 的DES加密算法
- 微信小程序:为了满足三方需求,我们一直在改变
- 让陌生人能够相互自由交易和支付
- 斯坦福发布首份 AI Index 报告,AI 研究者不再茫然
- jQuery仿极客公园火箭发射“返回顶部”效果(初始篇)
- Java程序员必读,Java设计模式应该遵循哪些原则
- Visual Studio 2010快速参考指南里头的Scrum海报
- TFS2010 Team Project Collections
- 基于Ext.Panel扩展一个更容易操作的Canvas
- 好玩的效果很好的Html游戏和范例
- jQuery仿极客公园火箭发射“返回顶部”效果(优化篇)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Prometheus Operator 常用指标
- Prometheus 常用 PromQL 语句
- 小游戏互动能力升级,获取未注册好友名单,定向分享
- 这年头还不会SpringBoot?
- PB级大规模Elasticsearch集群运维与调优实践
- 长假慢学,用TensorFlow做了个AI游戏
- 微服务平台之API授权
- 一些让人恶心的代码片段
- 一个依赖搞定 Spring Boot 反爬虫,防止接口盗刷!
- 还在用Swagger(丝袜哥)生成接口文档?我推荐你试试它...
- 技术分享 | 企业版监控工具 MEM 初探
- Java自动化测试(TestNg 10)
- LeetCode109:有序列表转二叉搜索树
- docker和docker-compose
- IDA-完整解析sig