简单Web服务器
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLDecoder;
import java.util.StringTokenizer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* 用Java语言实现HTTP服务器,首先启动一个java.net.ServerSocket在提供服务的端口上监听连接.向客户返回文本时,可以用
* PrintWriter,但是如果返回二进制数据,则必须使用OutputStream.write(byte[])方法,返回的应答消息字符串可以使用
* String.getBytes()方法转换为字节数组返回,或者使用PrintStream的print()方法写入文本,用
* write(byte[])方法写入二进制数据.
*
* 以工程所在目录为web的根目录。 在工程的根目录下放一个大概如下的index.html
*
* <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
* "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta
* http-equiv="Content-Type" content="text/html; charset=gbk">
* <title>简单的测试</title> </head> <body> 你好!这是一个 简单的web服务器。<br>
* 这是一个图片!<br>
*
* <form action="/index.html"> <img alt="" src="data:images/test.gif"><br>
* 姓名:<input type="text" name="name" /><br>
* 密码:<input type="password" name="pass"></input><br>
* <input type="submit"/> </form> </body> </html>
*
* 放入图片位置: 工程根目录/images/test.gif <br>
* 打开浏览器输入http://localhost/index.html 可以展示index.html
*
* @author rommel1
*/
public class SimpleHttpServer { ServerSocket serverSocket;// 服务器Socket
ExecutorService pool = Executors.newFixedThreadPool(2); /**
* 服务器监听端口, 默认为 80.
*/
public static int PORT = 80;// 标准HTTP端口 /**
* 开始服务器 Socket 线程.
*/
public SimpleHttpServer() {
try {
serverSocket = new ServerSocket(PORT);
} catch (Exception e) {
System.out.println("无法启动HTTP服务器:" + e.getMessage());
}
if (serverSocket == null)
System.exit(1);// 无法开始服务器 // new Thread(this).start();
System.out.println("HTTP服务器正在运行,端口:" + PORT);
while (true) {
pool.execute(new Process(serverSocket));
}
} /**
* 运行服务器主线程, 监听客户端请求并返回响应.
*/ /** */
/**
* 启动 HTTP 服务器
*
* @param args
*/
public static void main(String[] args) {
try {
if (args.length != 1) {
System.out.println("这是一个简单的web服务器 ,端口是: 80.");
} else if (args.length == 1) {
PORT = Integer.parseInt(args[0]);
}
} catch (Exception ex) {
System.err.println("服务器初始化错误" + ex.getMessage());
} new SimpleHttpServer();
}
} class Process extends Thread {
private ServerSocket serverSocket;// 服务器Socket Process(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
} public void run() {
try {
Socket client = null;// 客户Socket
client = serverSocket.accept();// 客户机(这里是 IE 等浏览器)已经连接到当前服务器
if (client != null) {
System.out.println("连接到服务器的用户:" + client);
try {
// 第一阶段: 打开输入流
BufferedReader in = new BufferedReader(new InputStreamReader(
client.getInputStream())); System.out.println("客户端发送的请求信息: ***************");
// 读取第一行, 请求地址
System.out.println("http协议头部信息:");
String line = in.readLine();
System.out.println(line);
String resource = line.substring(line.indexOf('/'), line.lastIndexOf('/') - 5);
// 获得请求的资源的地址
resource = URLDecoder.decode(resource, "gbk");// 反编码 String method = new StringTokenizer(line).nextElement().toString();// 获取请求方法,
// GET
// 或者
// POST // 读取浏览器发送过来的请求参数头部信息
while ((line = in.readLine()) != null) {
System.out.println(line); if (line.equals(""))
break;
} System.out.println("http协议头部结束 ***************");
System.out.println("用户请求的资源是:" + resource);
System.out.println("请求的类型是: " + method); String params = null; if (resource.indexOf("?") > -1) {
params = resource.substring(resource.indexOf("?") + 1);
resource = resource.substring(0, resource.indexOf("?"));
} // 显示 POST 表单提交的内容, 这个内容位于请求的主体部分
if ("POST".equalsIgnoreCase(method)) {
if (params != null) {
params += "&" + in.readLine();
} else {
params = in.readLine();
}
} System.out.println("打印提交的数据:");
printParams(params); // 读取资源并返回给客户端
fileReaderAndReturn(resource, client);
// 关闭客户端链接
client.close();
System.out.println("客户端返回完成!");
} catch (Exception e) {
System.out.println("HTTP服务器错误:" + e.getMessage());
}
} } catch (Exception e) {
System.out.println("HTTP服务器错误:" + e.getMessage());
}
} /**
* 读取一个文件的内容并返回给浏览器端.
*
* @param fileName
* 文件名
* @param socket
* 客户端 socket.
* @throws IOException
*/
void fileReaderAndReturn(String fileName, Socket socket) throws IOException {
if ("/".equals(fileName)) {// 设置欢迎页面,呵呵!
fileName = "/index.html";
}
fileName = fileName.substring(1); PrintStream out = new PrintStream(socket.getOutputStream(), true);
File fileToSend = new File(fileName); String fileEx = fileName.substring(fileName.indexOf(".") + 1);
String contentType = null;
// 设置返回的内容类型
// 此处的类型与tomcat/conf/web.xml中配置的mime-mapping类型是一致的。测试之用,就写这么几个。
if ("htmlhtmxml".indexOf(fileEx) > -1) {
contentType = "text/html;charset=GBK";
} else if ("jpegjpggifbpmpng".indexOf(fileEx) > -1) {
contentType = "application/binary";
} if (fileToSend.exists() && !fileToSend.isDirectory()) {
// http 协议返回头
out.println("HTTP/1.0 200 OK");// 返回应答消息,并结束应答
out.println("Content-Type:" + contentType);
out.println("Content-Length:" + fileToSend.length());// 返回内容字节数
out.println();// 根据 HTTP 协议, 空行将结束头信息 FileInputStream fis = null;
try {
fis = new FileInputStream(fileToSend);
} catch (FileNotFoundException e) {
out.println("<h1>404错误!</h1>" + e.getMessage());
}
byte data[];
try {
data = new byte[fis.available()]; fis.read(data);
out.write(data);
} catch (IOException e) {
out.println("<h1>500错误!</h1>" + e.getMessage());
e.printStackTrace();
} finally {
out.close();
try {
fis.close();
} catch (IOException e) { e.printStackTrace();
}
}
} else {
out.println("<h1>404错误!</h1>" + "文件没有找到");
out.close(); } } void printParams(String params) throws IOException {
if (params == null) {
return;
}
String[] maps = params.split("&");
for (String temp : maps) {
String[] map = temp.split("=");
System.out.println(map[0] + "==" + map[1]);
}
} }
简单Web服务器的更多相关文章
- C#中使用Socket实现简单Web服务器
上一篇博客中介绍了怎样使用socket访问web服务器.关键有两个: 熟悉Socket编程: 熟悉HTTP协议. 上一篇主要是通过socket来模拟浏览器向(任何)Web服务器发送(HTTP)请求,重 ...
- tomcat解析之简单web服务器(图)
链接地址:http://gogole.iteye.com/blog/587163 之前有javaeyer推荐了一本书<how tomcat works>,今天晚上看了看,确实不错,第一眼就 ...
- Socket网络编程--简单Web服务器(1)
这一次的Socket系列准备讲Web服务器.就是编写一个简单的Web服务器,具体怎么做呢?我也不是很清楚流程,所以我找来了一个开源的小的Web服务器--tinyhttpd.这个服务器才500多行的代码 ...
- Socket网络编程--简单Web服务器(6)
本来是想实现ssl连接的,但是弄了好久都不成功,就索性不做了,等以后有能力再做了.所以这一小节就是本次的最后一节了.就简单的说几个注意点. 1.加个配置文件 使用单例模式,使用一个类,该类保存一些信息 ...
- Java 18 新特性:简单Web服务器 jwebserver
在今年3月下旬的时候,Java版本已经更新到了18.接下来DD计划持续做一个系列,主要更新从Java 9开始的各种更新内容,但我不全部都介绍,主要挑一些有意思的内容,以文章和视频的方式来给大家介绍和学 ...
- 理解与模拟一个简单web服务器
先简单说下几个概念,根据自己的理解,不正确请见谅. web服务器 首先要知道什么是web服务器,简单说web服务器就是可以使用HTTP传输协议与客户端进行通信的服务器.最初的web服务器只能用来处理静 ...
- 自己实现简单Web服务器,支持GET POST请求
最近项目上遇到一个需求,最后想到的解决方案是自己实现一个web服务器去处理请求,然后再将信息发送到另外一个程序.然后返回处理之后的结果呈现出来. 现在我就来分享一下如何实现的. 通过.NET 为我们提 ...
- java实现简单web服务器(分析+源代码)
在日常的开发中,我们用过很多开源的web服务器,例如tomcat.apache等等.现在我们自己实现一个简单的web服务器,基本的功能就是用户点击要访问的资源,服务器将资源发送到客户端的浏览器.为了简 ...
- Socket网络编程--简单Web服务器(2)
上一小节通过阅读开源的Web服务器--tinyhttpd.大概知道了一次交互的请求信息和应答信息的具体过程.接下来我就自己简单的实现一个Web服务器. 下面这个程序只是实现一个简单的框架出来.这次先实 ...
- Socket网络编程--简单Web服务器(3)
上一小节已经实现了浏览器发送请求,然后服务器给出应答信息,然后浏览器显示出服务器发送过来的网页.一切看起来都是那么的美好.这一小节就准备实现可以根据地址栏url的不同来返回指定的网页.目前还不考虑带参 ...
随机推荐
- 网易实战分享|云信IM SDK接口设计实践
引语 IM (Instant Messaging)是网络上最流行的通信方式,与日常生活息息相关.IM软件也层出不穷,例如:微信.QQ.易信等.通过多年深耕和技术沉淀,云信产出了一套成熟稳定的IM SD ...
- 01-flask电商项目开发基础配置
本项目前端采用vue-cli的脚手架,后端采用Flask的Web框架.项目通过完成用户管理.权限管理.商品管理.订单管理.统计管理等功能,综合了前后端的知识,希望使大家都能受益. 1.使用到的技术如下 ...
- js 自定义阻止事件冒泡函数
// 以下改方法全兼容Chrome function stopBubble(event){ if(event.stopPropagation){ // 兼容火狐(firebox) event.st ...
- js 中 attachEvent 简示例
attachEvent绑定事件,函数的默认this指向为window,要解决问题可以通过call改变方法的指向! var div = document.getElementsByTagName('di ...
- Redis之对象
1.对象的类型与编码 Redis使用对象来表示数据库中的键和值,每次我们在Redis的数据库中新创建一个键值对,我们至少会创建两个对象,一个键对象,另一个值对象. 每个对象都由一个redisObjec ...
- 深入浅出Semaphore源码解析
Semaphore通过permits的值来限制线程访问临界资源的总数,属于有限制次数的共享锁,不支持重入. 前提条件 在理解Semaphore时需要具备一些基本的知识: 理解AQS的实现原理 之前有写 ...
- 数据库-SQL查询语言(一)
SQL数据定义 DDL sql的DDL不仅能定义一组关系,还能定义每个关系的信息,包括: 每个关系的模式 每个属性的取值类型 完整性约束 每个关系的维护的索引集合 每个关系的安全性和权限信息 每个关系 ...
- Shell基本语法---处理海量数据的awk命令
awk命令 其实是一门编程语言,支持条件判断,数组,循环等功能,与grep,sed被称为linux三剑客 之所以叫AWK是因为取其三位创始人 Alfred Aho,Peter Weinberger, ...
- socket链接
服务端: package com.batch.service.impl; import java.io.BufferedReader; import java.io.BufferedWriter; i ...
- C++11 STL Regex正则表达式与字符串字段解析
简单的日期正则表达式 一个简单的日期解析程序,从yyyy-mm-dd格式的日期字符串中,分别获取年月日. 先设置一个简单的正则表达式,4位数字的"年",1-2位数字的"月 ...