自己实现一个简易web服务器
一个web服务器是网络应用中最基础的环节。
构建需要理解三个内容:
1.http协议
2.socket类
3.服务端实现原理
1.1 HTTP
http请求
一般一个http请求包括以下三个部分:
1 请求方法,如get,post
2 请求头
3 实体
1.2http响应
与http请求类似,http响应也包括三个部分
1 协议-状态码-描述
2 响应头
3 响应实体段
2.Socket
2.1不同的应用程序可以通过套接字发送或接受字节流。java中提供了Socket类来实现这个功能。
2.2光靠Socket类还是不能够实现我们构建一个服务器应用程序的功能的,因为服务器必须时刻待命,因此java里面提供了ServerSocket类来处理等待来自客户端的请求,当ServerSocket接受到了来自客户端的请求之后,它就会创建一个实例来处理与客户端的通信。
3.实现原理
3.1构建一个封装请求信息的类requst,一个响应请求的类response,还要有一个主程序httpServer来处理客户端来的请求
下面是一个requst类,主要处理uri
package com.lwq; import java.io.IOException;
import java.io.InputStream; /** * 将浏览器发来的请求信息转化成字符和截取url
*/
public class Request {
//输入流
private InputStream input;
//截取url,如http://localhost:8080/index.html ,截取部分为 /index.html
private String uri;
public Request(InputStream inputStream){
this.input = inputStream;
}
public InputStream getInput() {
return input;
}
public void setInput(InputStream input) {
this.input = input;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
//从套接字中读取字符信息
public void parse(){
StringBuffer request = new StringBuffer(2048);
int i = 0;
byte[] buffer = new byte[2048]; try {
i = input.read(buffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
i = -1;
}
for(int j = 0;j<i;j++){
request.append((char)(buffer[j]));//拼接请求字符串
}
System.out.println(request.toString());
uri = parseUri(request.toString());//截取url,存入uri字段
}
//截取请求的url
private String parseUri(String requestString){
int index1 = 0;
int index2 = 0;
index1 = requestString.indexOf(' ');
if(index1!=-1){
index2 = requestString.indexOf(' ',index1+1);
if(index2>index1){
return requestString.substring(index1+1,index2);
}
}
return null;
}
}
下面是封装了响应请求的类response,用于返回文件或数据
package com.lwq; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter; /** * 类说明 根据相应信息返回结果
*/
public class Response { private static final int BUFFER_SIZE = 1024;
Request request;
OutputStream output;
public Response(OutputStream output){
this.output = output;
} public void sendStaticResource() throws IOException{
byte[] bytes = new byte[BUFFER_SIZE];
FileInputStream fis = null;
File file = new File(HttpServer.WEB_ROOT,request.getUri());
if(file.exists()){
try {
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);
} } catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}finally{
if(fis !=null){
fis.close();
}
}
}else{
//找不到文件
String errorMessage = "HTTP/1.1 404 File Not Found\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length: 23\r\n" +
"\r\n" +
"
File Not Found
";
try {
output.write(errorMessage.getBytes());
output.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public Request getRequest() {
return request;
}
public void setRequest(Request request) {
this.request = request;
}
public OutputStream getOutput() {
return output;
}
public void setOutput(OutputStream output) {
this.output = output;
}
public static int getBUFFER_SIZE() {
return BUFFER_SIZE;
}
}
主程序:
package com.lwq; import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket; /** * 类说明
*/
public class HttpServer {
/**
* @param args
*/ //WEB_ROOT是服务器的根目录
public static final String WEB_ROOT = System.getProperty("user.dir")+File.separator+"webroot"; //关闭的命令
private static final String SHUTDOWN_COMMAND= "/SHUTDOWN"; public static void main(String[] args) {
// TODO Auto-generated method stub
HttpServer server = new HttpServer();
server.await(); }
public void await(){
ServerSocket serverSocket = null;
int port = 8080;
try {
serverSocket = new ServerSocket(port,1,InetAddress.getByName("127.0.0.1"));
while(true)
{
try {
Socket socket = null;
InputStream input = null;
OutputStream output = null;
socket = serverSocket.accept();
input = socket.getInputStream();
output = socket.getOutputStream();
//封装request请求
Request request = new Request(input);
request.parse();
//封装response对象
Response response = new Response(output);
response.setRequest(request);
response.sendStaticResource();
socket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
continue;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行httpServer,在浏览器中打下http://localhost:8080/index.jsp,就能看到服务器响应的结果了。
侵删。
自己实现一个简易web服务器的更多相关文章
- 写一个简易web服务器、ASP.NET核心知识(4)--转载
第一次尝试(V1.0) 1.理论支持 这里主要要说的关于Socket方面的.主要是一个例子,关于Socket如何建立服务端程序的简单的代码. static void Main(string[] arg ...
- 写一个简易web服务器、ASP.NET核心知识(4)
前言 昨天尝试了,基于对http协议的探究,我们用控制台写了一个简单的浏览器.尽管浏览器很low,但是对于http协议有个更好的理解. 说了上面这一段,诸位猜到我要干嘛了吗?(其实不用猜哈,标题里都有 ...
- Socket 初识 用Socket建立一个简易Web服务器
摘自<Asp.Net 本质论>作者:郝冠军 //在.Net中.system.Net命名空间提供了网络编程的大多数数据据类型以及常用操作,其中常用的类型如下: /* IPAddress 类表 ...
- 深入理解Tornado——一个异步web服务器
本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...
- Node:使用express搭建一个简易的服务器
①安装node环境 在node.js官网下载LTS长期支持版本,然后傻瓜式安装 ②查看是否安装成功 打开cmd终端,输入node -v 有版本号,则安装成功.再输入npm -v 有版本号,则npm也安 ...
- python -m http.server 搭建一个简易web下载服务器
在打vulnhub靶场的时候遇到的一个问题 目录 一.进到需要发送的安装包目录 二.开启http服务 三.访问服务器 一.进到需要发送的安装包目录 比如设置一个专门发送,传输的文件的文件夹,cmd命令 ...
- Anroid搭建一个局域网Web服务器
前言 很多开发者看到这个标题表示很怪异,Android怎么可能搭建服务器呢?根本用不到呀,这个项目毫无价值.我表示很理解这一类的开发者,毕竟每个人的经验经历都是有限的. 必须要说说我们的用处(需要 ...
- [js高手之路]node js系列课程-创建简易web服务器与文件读写
web服务器至少有以下几个特点: 1.24小时不停止的工作,也就是说这个进程要常驻在内存中 2.24小时在某一端口监听,如: http://localhost:8080, www服务器默认端口80 3 ...
- 手写简易WEB服务器
今天我们来写一个类似于Tomcat的简易服务器.可供大家深入理解一下tomcat的工作原理,本文仅供新手参考,请各位大神指正!首先我们要准备的知识是: Socket编程 HTML HTTP协议 服务器 ...
随机推荐
- 关于Java中进程和线程的详解
一.进程:是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个动态的实体,它有自己的生命 周期.它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而 ...
- 一步步学习javascript基础篇(7):BOM和DOM
一.什么是BOM.什么是DOM BOM即浏览器对象模型,主要用了访问一些和网页无关的浏览器功能.如:window.location.navigator.screen.history等对象. DOM即文 ...
- .NET开发邮件发送功能的全面教程(含邮件组件源码)
今天,给大家分享的是如何在.NET平台中开发“邮件发送”功能.在网上搜的到的各种资料一般都介绍的比较简单,那今天我想比较细的整理介绍下: 1) 邮件基础理论知识 2) ...
- MapReduce剖析笔记之三:Job的Map/Reduce Task初始化
上一节分析了Job由JobClient提交到JobTracker的流程,利用RPC机制,JobTracker接收到Job ID和Job所在HDFS的目录,够早了JobInProgress对象,丢入队列 ...
- Egret 集成第三方库 记录
引入第三方库pureMVC 这次我们要使用到一个mvc开发框架-pureMVC,熟悉as3的朋友一定也对这个框架不陌生吧.不熟悉的也没关系,这个框架不是这次的主角.我们从 这里 下载pureMVC的T ...
- web全栈开发之网站开发一(Mac环境配置)
个人第一次写博客,想给大家分享的是PHP+HTML5+MySQL开发一个个人网站所需的部分技术,希望能帮到志同道合和开发者,别人小白高手勿喷就行 先说一下我在制作这个网站之前的配置: 我用的是MacB ...
- Electron中Jquery的引入方式
原文链接http://huisky.com/blog/16122220522957 Electron默认启用了Node.js的require模块,而jQuery等新版本框架为了支持commondJS标 ...
- QunInfo群数据库的还原与优化
一. 背景 这个数据库的数据文件mdf大概有8.5G左右,当还原数据库之后感觉可以做很多性能方面上的调优,合并数据后mdf数据文件大概有6.2G左右,行压缩后mdf数据文件大概有4.8G左右,页压缩后 ...
- 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(14)-EasyUI缺陷修复与扩展
系列目录 不知不觉已经过了13讲,(本来还要讲多一讲是,数据验证之自定义验证,基于园友还是对权限这块比较敢兴趣,讲不讲验证还是看大家的反映),我们应该对系统有一个小结.首先这是一个团队开发项目,基于接 ...
- 原生Ajax总结
HTTP协议 传统的请求和Ajax请求 Ajax定义 Asynchronous JavaScript and XML. Ajax异步的,JavaScript程序希望与服务器直接通信而不需要重新加载页面 ...