一个简单的web服务器例子
一个简单的web容器小例子,功能十分简单,只能访问静态资源,对于新手来说还是有一定的意义。主要分三个类
1、server类:主要功能开启socketServer,阻塞server,接收socket访问,解析request,创建request,作出响应
public class TestServer1 { private boolean shutdown = false; // web目录webroot
public static final String WEB_ROOT = System.getProperty("user.dir")
+ File.separator + "WebRoot"; public static final String SHUTDOWN_COMMAND = "/SHUTDOWN"; public static void main(String[] args) {
TestServer1 server = new TestServer1();
server.await();
} public void await() { // 第一步、创建出serverSocket监听本机8080端口
ServerSocket server = null;
int port = 8080;
try {
server = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
} catch (Exception e) {
e.printStackTrace();
} // 第二步、轮询阻塞住socketServer
while(!shutdown) {
Socket socket = null;
InputStream input = null;
OutputStream output = null; try {
socket = server.accept();
input = socket.getInputStream();
output = socket.getOutputStream(); // 第三步、创建出request,解析request请求
Request req = new Request(input);
req.parseRequest(); // 第四步、创建response
Response response = new Response(output);
response.setRequest(req); // 第五步、发送简单静态资源,关闭socket结束本次会话
response.sendStaticRes();
socket.close(); // 关闭指令
shutdown = req.getUri().equals(SHUTDOWN_COMMAND);
} catch (IOException e) {
e.printStackTrace();
}
} } }
当然了上面的是最简单的实现,也不能实现多线程,实际上的web容器肯定会创建一个线程池来接收请求
2、request 主要的工作解析input流,封装成request
class Request { private InputStream input; private String uri; public Request(InputStream input) {
this.input = input;
} /**
* 解析request请求内容
* GET /index.html HTTP/1.1
* Accept: text/html, application/xhtml+xml, *//*
* Accept-Language: zh-CN
* User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; MALCJS; rv:11.0) like Gecko
* Accept-Encoding: gzip, deflate
* Host: localhost:8080
* DNT: 1
* Connection: Keep-Alive
* Cookie: 这个地方应该如果有cookie,如果有session还有jsessionId的
*/
public void parseRequest() {
// 为什么只获取2048个字符,这是因为request请求内容的长度,出于安全或者其他方面的考虑,在浏览器端和服务器端都会做这么一个限制。
StringBuffer buffer = new StringBuffer(2048);
byte[] bytes = new byte[2048];
int i;
try {
i = input.read(bytes);
} catch (IOException e) {
e.printStackTrace();
i=-1;
} for(int k=0; k<i; k++) {
buffer.append((char)bytes[k]);
}
System.out.println(buffer.toString());
uri = parseUri(buffer.toString());
} /**
* GET /index.html HTTP/1.1 uri的位置
* @param reqStr
* @return
*/
private String parseUri(String reqStr) {
int index1, index2;
index1 = reqStr.indexOf(' ');
if (index1 != -1) {
index2 = reqStr.indexOf(' ', index1 + 1);
if (index2 > index1)
return reqStr.substring(index1 + 1, index2);
}
return null;
} public String getUri() {
return uri;
} }
解析成的http请求的具体内容,作为web开发人员应该要熟悉每个字段的意义,这个请求是浏览器本身按照http协议封装的一个请求,能够手写出这个请求当然更好。
3、response 通过request的uri找到对应的资源对请求作出响应,实际的情况肯定是有静态和动态资源例如servlet\filter等等,但是这里只是做了简单的静态的处理了
class Response { private OutputStream output; private Request request; public Response(OutputStream output) {
this.output = output;
} public void setRequest(Request req) {
this.request = req;
} /**
* 简单处理静态资源
* @throws IOException
*/
public void sendStaticRes() throws IOException { FileInputStream fis = null;
try {
File staticFile = new File(TestServer1.WEB_ROOT, request.getUri());
if(staticFile.exists()) {
fis = new FileInputStream(staticFile);
int i = 0;
byte[] buf = new byte[1024];
// 流的对拷
i = fis.read(buf, 0, 1024);
while(i!=-1) {
output.write(buf, 0, i);
i = fis.read(buf, 0, 1024);
}
} else {
// file not found 404
String 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) {
e.printStackTrace();
} finally{
if(fis!=null)
fis.close();
fis = null;
}
}
}
同样响应内容你也应该要熟悉哪些组成部分
HTTP/1.1 200 OK //响应行
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122 <html>
<head>
<title>Test</title>
</head>
<body>
This my page
</body>
</html>
至此一个简单的web容器就写好了,能够访问webRoot目录下的静态资源。
可以通过浏览器访问,也可以通过telnet端进行访问。在cmd命令行下telnet localhost 8080,就会连接上socketServer,然后就会等待输入,自然我们输入对应的请求报文,回车响应内容就出现了。
以上原创文章出自老罗家的树博客地址:http://www.cnblogs.com/TimBing/
一个简单的web服务器例子的更多相关文章
- 自己动手模拟开发一个简单的Web服务器
开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...
- 一个简单的web服务器
写在前面 新的一年了,新的开始,打算重新看一遍asp.net本质论这本书,再重新认识一下,查漏补缺,认认真真的过一遍. 一个简单的web服务器 首先需要引入命名空间: System.Net,关于网络编 ...
- [置顶] 在Ubuntu下实现一个简单的Web服务器
要求: 实现一个简单的Web服务器,当服务器启动时要读取配置文件的路径.如果浏览器请求的文件是可执行的则称为CGI程序,服务器并不是将这个文件发给浏览器,而是在服务器端执行这个程序,将它的标准输出发给 ...
- Tomcat剖析(一):一个简单的Web服务器
Tomcat剖析(一):一个简单的Web服务器 1. Tomcat剖析(一):一个简单的Web服务器 2. Tomcat剖析(二):一个简单的Servlet服务器 3. Tomcat剖析(三):连接器 ...
- 自己模拟的一个简单的web服务器
首先我为大家推荐一本书:How Tomcat Works.这本书讲的很详细的,虽然实际开发中我们并不会自己去写一个tomcat,但是对于了解Tomcat是如何工作的还是很有必要的. Servlet容器 ...
- 2.1 一个简单的Web工程例子
一个简单的Web工程例子 开发环境: Eclipse: Neon Release (4.6.0) JDK:1.8.0_92 Tomcat:8.5.9 Maven:3.3.9 1. 在Eclipse中创 ...
- 利用 nodeJS 搭建一个简单的Web服务器(转)
下面的代码演示如何利用 nodeJS 搭建一个简单的Web服务器: 1. 文件 WebServer.js: //-------------------------------------------- ...
- 《深度解析Tomcat》 第一章 一个简单的Web服务器
本章介绍Java Web服务器是如何运行的.从中可以知道Tomcat是如何工作的. 基于Java的Web服务器会使用java.net.Socket类和java.net.ServerSocket类这两个 ...
- 一个简单的Web服务器-支持Servlet请求
上接 一个简单的Web服务器-支持静态资源请求,这个服务器可以处理静态资源的请求,那么如何处理Servlet请求的呢? 判断是否是Servlet请求 首先Web服务器需要判断当前请求是否是Servle ...
随机推荐
- Java基础—异常处理总结
异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地 ...
- [转]NHibernate之旅(2):第一个NHibernate程序
本节内容 开始使用NHibernate 1.获取NHibernate 2.建立数据库表 3.创建C#类库项目 4.设计Domain 4-1.设计持久化类 4-2.编写映射文件 5.数据访问层 5-1. ...
- UVA 11624 Fire! (bfs)
算法指南白书 分别求一次人和火到达各个点的最短时间 #include<cstdio> #include<cstring> #include<queue> #incl ...
- ubuntu 手动添加jar到本地仓库
前言:maven仓库的下载速度太慢了,而且有些jar不存在,或者加入自己开发的依赖包,还是要学会自己手动加入jar.下面以 javax.servlet-api为例. 1.获取下载的javax.serv ...
- java数据结构-非线性结构之树
一.树状图 树状图是一种数据结构,它是由n(n>=1)个有限节点组成的具有层次关系的集合.因其结构看起来想个倒挂的树,即根朝上,叶子在下,故被称为"树". 特点: 1. 每个 ...
- 6步骤实现CentOS系统环境精简优化
6步骤实现CentOS系统环境精简优化 发布时间:2014-11-03 14:59:27 编辑:AHLinux.com 第一步.删除不必要的自带软件包yum remove Deployment_G ...
- NPOI组件集锦
关于NPOI不错的介绍:http://www.cnblogs.com/restran/p/3889479.html http://www.cnblogs.com/Irving/archive/2012 ...
- PAT---1013. Battle Over Cities (25)
这道题目的意思是:在战争时代,如果一个城市被敌人占领了,那么和该城市相连的道路都必须关闭,我们必须把剩下的城市(即不包括被敌人占领的城市)连接起来. 举个例子,我们有3个城市,C1,C2,C3,C1和 ...
- PAT---1050. String Subtraction (20)
#include<iostream> #include<string.h> #include<stdio.h> using namespace std; #defi ...
- php通过文件头检测文件类型通用类(zip,rar…)(转)
在做web应用时候,通过web扩展名判断上存文件类型,这个是我们常使用的.有时候我们这样做还不完善.可能有些人上存一些文件,但是他通过修改 扩展名,让在我们的文件类型之内. 单实际访问时候又不能展示( ...