单文件服务器

导语

在研究HTTP服务器时,我们可以从一个单文件服务器开始。无论接受到什么请求,这个服务器始终发送同一个文件。下面是示例代码,绑定的端口,发送的文件名以及文件的编码从命令行读取。如果省略端口则假定为端口80,如果省略编码方式默认8080

示例代码

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Logger; public class SingleHttpServer {
private static final Logger logger = Logger.getLogger("SingleFileHttpServer");
private static Handler handler;
private final byte[] content;
private final byte[] header;
private final int port;
private final String encoding; public SingleHttpServer(String _content, String _encoding, String mimeType, int _port) {
this(_content.getBytes(), _encoding, mimeType, _port);
} public SingleHttpServer(byte[] _content, String _encoding, String mimeType, int _port) {
try {
handler = new FileHandler("SingleFileHttpServer.log");
} catch (Exception e) {
throw new RuntimeException("cannot create log file!");
}
logger.addHandler(handler);
content = _content;
encoding = _encoding;
String header1 = "HTTP/1.1 200 OK\r\n"
+ "Server: OneFile\r\n"
+ "Content-length: "+ content.length +"\r\n"
+ "Content-Type: " + mimeType + ";charset=" + encoding + "\r\n\r\n";
header = header1.getBytes(Charset.forName("utf-8"));
port = _port;
} public void start() {
ExecutorService pool = Executors.newFixedThreadPool(100);
try (ServerSocket server = new ServerSocket(port)) {
logger.info("Accepting connections on port " + server.getLocalPort());
logger.info("Data to be sent:");
logger.info(new String(content, encoding));
while (true) {
Socket socket = server.accept();
pool.execute(new HttpHandler(socket));
}
} catch (IOException e) {
e.printStackTrace();
}
} private class HttpHandler implements Runnable { private final Socket socket; public HttpHandler(Socket _socket) {
socket = _socket;
} @Override
public void run() {
try (
OutputStream out = new BufferedOutputStream(socket.getOutputStream());
InputStream in = new BufferedInputStream(socket.getInputStream());
) {
StringBuilder request = new StringBuilder(80);
while (true) {
int c = in.read();
if (c == '\r' || c == '\n' || c == -1)break;
request.append((char)c);
}
if (request.toString().indexOf("HTTP/") != -1) {
out.write(header);
}
out.write(content);
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
} public static void main(String[] args) { //设置端口
int port;
try{
port = Integer.parseInt(args[2]);
if (port < 1 || port > 65535)
port = 8080;
} catch (RuntimeException e) {
//如果参数中没有端口,则会发生数组越界,所以需要捕获
port = 8080;
}
//设置编码方式
String encoding = "UTF-8";
if (args.length >= 2) encoding = args[1]; try {
Path path = Paths.get(args[0]).toAbsolutePath();
byte[] data = Files.readAllBytes(path);
String contentType = URLConnection.getFileNameMap().getContentTypeFor(path.toString());
SingleHttpServer server = new SingleHttpServer(data, encoding, contentType, port);
server.start();
} catch (ArrayIndexOutOfBoundsException ex) {
System.out.println("Usage: java SingleHttpServer filename [encoding [port]]");
} catch (IOException e) {
logger.severe(e.getMessage());
}
}
}

main()方法中是从命令行读取参数。从第一个命令行读取提供的文件名。如果没有指定文件或者如果文件无法打开,就显示一条错误信息,程序推出。假定文件能够读取,就是用java7引入的Path和Files类将其内容读入byte数组。URLConnection类对文件的内容类型做出合理的猜测,将猜测的结果保存到contentTyep变量中。接下来读取第二个参数,如果没有则指定编码方式为UTF-8。

HTTP服务器(1)的更多相关文章

  1. App开发:模拟服务器数据接口 - MockApi

    为了方便app开发过程中,不受服务器接口的限制,便于客户端功能的快速测试,可以在客户端实现一个模拟服务器数据接口的MockApi模块.本篇文章就尝试为使用gradle的android项目设计实现Moc ...

  2. 闰秒导致MySQL服务器的CPU sys过高

    今天,有个哥们碰到一个问题,他有一个从库,只要是启动MySQL,CPU使用率就非常高,其中sys占比也比较高,具体可见下图. 注意:他的生产环境是物理机,单个CPU,4个Core. 于是,他抓取了CP ...

  3. 闲来无聊,研究一下Web服务器 的源程序

    web服务器是如何工作的 1989年的夏天,蒂姆.博纳斯-李开发了世界上第一个web服务器和web客户机.这个浏览器程序是一个简单的电话号码查询软件.最初的web服务器程序就是一个利用浏览器和web服 ...

  4. SignalR系列续集[系列8:SignalR的性能监测与服务器的负载测试]

    目录 SignalR系列目录 前言 也是好久没写博客了,近期确实很忙,嗯..几个项目..头要炸..今天忙里偷闲.继续我们的小系列.. 先谢谢大家的支持.. 我们来聊聊SignalR的性能监测与服务器的 ...

  5. 使用 Nodejs 搭建简单的Web服务器

    使用Nodejs搭建Web服务器是学习Node.js比较全面的入门教程,因为要完成一个简单的Web服务器,你需要学习Nodejs中几个比较重要的模块,比如:http协议模块.文件系统.url解析模块. ...

  6. 通过ProGet搭建一个内部的Nuget服务器

    .NET Core项目完全使用Nuget 管理组件之间的依赖关系,Nuget已经成为.NET 生态系统中不可或缺的一个组件,从项目角度,将项目中各种组件的引用统统交给NuGet,添加组件/删除组件/以 ...

  7. 谈谈如何使用Netty开发实现高性能的RPC服务器

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...

  8. 游戏服务器菜鸟之C#初探一游戏服务

    本人80后程序猿一枚,原来搞过C++/Java/C#,因为工作原因最后选择一直从事C#开发,因为读书时候对游戏一直比较感兴趣,机缘巧合公司做一个手游的项目,我就开始游戏服务器的折腾之旅. 游戏的构架是 ...

  9. 无法向会话状态服务器发出会话状态请求。请确保 ASP.NET State Service (ASP.NET 状态服务)已启动,并且客户端端口与服务器端口相同。如果服务器位于远程计算机上,请检查。。。

    异常处理汇总-服 务 器 http://www.cnblogs.com/dunitian/p/4522983.html 无法向会话状态服务器发出会话状态请求.请确保 ASP.NET State Ser ...

  10. SQL Server 无法连接到服务器。SQL Server 复制需要有实际的服务器名称才能连接到服务器。请指定实际的服务器名称。

    异常处理汇总-数据库系列  http://www.cnblogs.com/dunitian/p/4522990.html SQL性能优化汇总篇:http://www.cnblogs.com/dunit ...

随机推荐

  1. ASP.NET 截获服务器生成的将要发送到客户端的html的方法

    有时候我们需要在将服务器端生成的html发送带客户端之前对这些html进行操作,比如生成静态html加之保存.改变生成的html中的某些内容等等,那么久可以通过如下的方案解决. 我总结了两种方式,个人 ...

  2. Effective前端3:用CSS画一个三角形

    p { text-indent: 2em } .triangle-container p { text-indent: 0 } img { margin: 15px 0 } 三角形的场景很常见,打开一 ...

  3. 基于STM32Cube的IIC主从通信

    1.建立STM32Cube工程,我使用的芯片是STM32F429,为了更简单的建立单独的IIC通信任务,我使用了FREERTOS,另外选择了RCC(系统时钟初始化),I2C1,I2C2(为了验证代码的 ...

  4. 【WP8.1】WebView笔记

    之前在WP8的时候做过WebBrowser相关的笔记,在WP8.1的WebView和WebBrowser有些不一样,在这里做一些笔记 下面分为几个部分 1.禁止缩放 2.JS通知后台C#代码(noti ...

  5. JavaScript结构三层——思想快速介绍

    本文版权归博客园和作者吴双本人所有,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/,我是博客园蜗牛,我们共同进步. 今天讨论的是什么 如果你的工作中需要写JavaS ...

  6. Redis高可用集群方案——哨兵

    本篇文章版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文系列地址http://www.cnblogs.com/tdws/tag/NoSql/ 本人之前有篇文章,讲到了redis主从复制,读写分 ...

  7. Spring学习系列(一) Spring简介

    Spring简介 之前一直想写点东西,可一直没有开始实施,各种原因都有,最大原因可能还是自己太懒了,嘿嘿.最近在看Spring in action这本书,为了能让自己坚持下去把书看完,这次决定同步的在 ...

  8. Socket简单使用

    客户端代码: import java.io.*; import java.net.*; public class DailyAdviceClient { public void go(){ try{ ...

  9. Maven部署构件至远程仓库

    私服的一大作用就是部署第三方构件,包括组织内的生成的构件以及一些无法从外部仓库获取的构件.无论是日常开发中生成的构件,还是正式版本发布的构件,都需要部署到仓库中,供其它团队成员使用.Maven除了能对 ...

  10. 释放Android的函数式能量(I):Kotlin语言的Lambda表达式

    原文标题:Unleash functional power on Android (I): Kotlin lambdas 原文链接:http://antonioleiva.com/operator-o ...