阻塞式简易http服务器
- 说明
使用java.net包的ServerSocket也是阻塞的,所以下面的实例把ServerSocketChannel换成ServerSocket效果一样。
- 后台代码
package study.socket.tcp.block.httpserver; import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; /**
* 阻塞式简易http服务器
* @author yj
*
*/
public class SimpleHttpServer { private int port = 8080;
private ServerSocketChannel serverSocketChannel = null;
private ExecutorService executorService;
private static final int POOL_MULTIPE = 4; public SimpleHttpServer() throws Exception {
executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*POOL_MULTIPE);
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().setReuseAddress(true);
serverSocketChannel.socket().bind(new InetSocketAddress(port));
System.out.println("服务器启动");
} public void service() {
while(true) {
System.out.println("服务器接收到客户端请求");
SocketChannel socketChannel = null;
try {
socketChannel = serverSocketChannel.accept();
} catch (IOException e) {
e.printStackTrace();
}
executorService.execute(new Handler(socketChannel));
System.out.println("服务端处理完客户端请求");
}
} private class Handler implements Runnable { private SocketChannel socketChannel; public Handler(SocketChannel socketChannel) {
this.socketChannel = socketChannel;
} @Override
public void run() {
handler();
} private void handler() {
FileInputStream fis = null;
try{
new Thread().sleep(60000);
Socket socket = socketChannel.socket();
System.out.println("接受到客户连接来自:" + socket.getInetAddress() + ":" + socket.getPort());
ByteBuffer bb = ByteBuffer.allocate(1024);
socketChannel.read(bb);
bb.flip();
String request = decode(bb);
System.out.println("客户端请求消息:" + request);
//生成http响应消息
StringBuffer sb = new StringBuffer("HTTP/1.1 200 OK\r\n");
sb.append("Content-Type:text/html\r\n\r\n");
//发送http响应第一行和响应头
socketChannel.write(encode(sb.toString())); //获取http请求的第一行
String firstLineOfRequst = request.substring(0, request.indexOf("\r\n"));
String filePath = SimpleHttpServer.class.getResource("/").getPath();
System.out.println("路径:" + filePath);
System.out.println("测试");
if(firstLineOfRequst.indexOf("login.html") != -1) {
fis = new FileInputStream(filePath + "study/socket/block/httpserver/login.html");
}else {
fis = new FileInputStream(filePath + "study/socket/block/httpserver/hello.html");
}
FileChannel fc = fis.getChannel();
fc.transferTo(0, fc.size(), socketChannel);
}catch(Exception e){
e.printStackTrace();
}finally {
try {
if(fis != null) {
fis.close();
}
if(socketChannel != null) {
socketChannel.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
} private String decode(ByteBuffer bb) throws Exception{
Charset charset = Charset.forName("utf-8");
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode(bb);
System.out.println( " charBuffer= " + charBuffer);
System.out.println(charBuffer.toString());
System.out.println("编码");
return charBuffer.toString();
} private ByteBuffer encode(String str) {
System.out.println("解码");
return ByteBuffer.wrap(str.getBytes());
} } public static void main(String[] args) {
try {
new SimpleHttpServer().service();
} catch (Exception e) {
e.printStackTrace();
}
}
}
- hello.html文件
html文件放在类的同级目录下,如果放其他目录下,上面后台代码需要改变取html文件路径。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>hello</h1>
</body>
</html>
- login.html文件
html文件放在类的同级目录下,如果放其他目录下,上面后台代码需要改变取html文件路径。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>login</h1>
</body>
</html>
- 测试
浏览器中输入:http://ip:port/或http://ip:port/hello.html访问hello.html,输入:http://ip:port/login.html访问login.html
阻塞式简易http服务器的更多相关文章
- PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法
如今在电商行业里,秒杀抢购活动已经是商家常用促销手段.但是库存数量有限,而同时下单人数超过了库存量,就会导致商品超卖甚至库存变负数的问题. 又比如:抢购火车票.论坛抢楼.抽奖乃至爆红微博评论等也会引发 ...
- 阻塞式和非阻塞式IO
有很多人把阻塞认为是同步,把非阻塞认为是异步:个人认为这样是不准确的,当然从思想上可以这样类比,但方式是完全不同的,下面说说在JAVA里面阻塞IO和非阻塞IO的区别 在JDK1.4中引入了一个NIO的 ...
- Java IO(3)非阻塞式输入输出(NIO)
在上篇<Java IO(2)阻塞式输入输出(BIO)>的末尾谈到了什么是阻塞式输入输出,通过Socket编程对其有了大致了解.现在再重新回顾梳理一下,对于只有一个“客户端”和一个“服务器端 ...
- python 简单搭建非阻塞式单进程,select模式,epoll模式服务
由于经常被抓取文章内容,在此附上博客文章网址:,偶尔会更新某些出错的数据或文字,建议到我博客地址 : --> 点击这里 可以看我的上篇文章 <python 简单搭建阻塞式单进程,多进程, ...
- 非阻塞式I/O
套接字的默认状态是阻塞的.这就意味着当发出一个不能立即完成的套接字调用时,其进程将被投入睡眠,等待相应的操作完成.可能阻塞的套接字调用可分为以下4类 (1)输入操作,包括read,readv,recv ...
- 4.NIO的非阻塞式网络通信
/*阻塞 和 非阻塞 是对于 网络通信而言的*/ /*原先IO通信在进行一些读写操作 或者 等待 客户机连接 这种,是阻塞的,必须要等到有数据被处理,当前线程才被释放*/ /*NIO 通信 是将这个阻 ...
- Linux NIO 系列(02) 阻塞式 IO
目录 一.环境准备 1.1 代码演示 二.Socket 是什么 2.1 socket 套接字 2.2 套接字描述符 2.3 文件描述符和文件指针的区别 三.基本的 SOCKET 接口函数 3.1 so ...
- node--非阻塞式I/O,单线程,异步,事件驱动
1.单线程 不同于其他的后盾语言,node是单线程的,大大节约服务器开支 node不为每个客户创建一个新的线程,仅使用一个线程.通过非阻塞I/O以及 事件驱动机制,使其宏观上看是并发的,可以处理高并发 ...
- Node:使用express搭建一个简易的服务器
①安装node环境 在node.js官网下载LTS长期支持版本,然后傻瓜式安装 ②查看是否安装成功 打开cmd终端,输入node -v 有版本号,则安装成功.再输入npm -v 有版本号,则npm也安 ...
随机推荐
- 【翻译】View Frustum Culling --2 Geometric Approach – Extracting the Planes
在上一篇中,我们知道了视锥体的形状,并且也确定了我们进行裁剪时的步骤.那我们接下来要走的就是确定视锥体的六个平面: near, far, top, bottom, left and right 2.计 ...
- VM虚拟机 Centos7 lnmp环境 配置域名问题 windows浏览器访问的问题
CentOS7 ip地址为 192.168.0.155 搭有 LNMP集成环境 执行 lnmp vhost add 配置服务器 指定目录的域名 mark.com 这时windows 机器的 浏览器想 ...
- sql去除重复语句
转自芙蓉清秀的BLOG http://blog.sina.com.cn/liurongxiu1211 sql去除重复语句 (2012-06-15 15:00:01) sql 单表/多表查询去除重复记 ...
- DDMS 使用方法
一.真机调试的两个必备条件 (1)手机打开开发者模式并且运行USB调试 (2)PC上装好手机对应的驱动 二.DDMS(DalvikDebugMonitorServer)四个主要窗口 Devices:当 ...
- 牛客网Wannafly挑战赛15 B车辆安排(模拟)AND C 出队(规律)
传送门 :B题:点我 C题: 点我 题目描述 有n个队伍,每个队伍的人数小于等于5,每辆车最多坐5个人,要求一个队伍的人都在一辆车上,求最少的车数 输入描述: 第一行n第二行n个数,表示每个队伍的人数 ...
- Jasperreport5.6.9-----1
Jasperreport5.6.0生成PDF 最近项目中需要生成报表,先是看了下itext,觉得还可以,但是如果数据字段多的话,不太灵活.所以后来看了下ireport,觉得还可以,下面简单说一下它们: ...
- stm32架构初认识
刚接触stm32f373c8t6的芯片,这到底是怎末开发的,应该说它是SOC,内部有一个核心芯片,然后在芯片的外部添加了一些有特殊功能的外设,使开发者能够完成想要的功能,以stm32f373c 8t6 ...
- maven 打 fat包(jar包有了全部依赖)插件
<plugin> <artifactId> maven-assembly-plugin </artifactId> <configuration> &l ...
- TZOJ 1513 Farm Tour(最小费用最大流)
描述 When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 &l ...
- TZOJ 5291 游戏之合成(快速幂快速乘)
描述 zzx和city在玩一款小游戏的时候,游戏中有一个宝石合成的功能,需要m个宝石才可以合成下一级的宝石(例如需要m个1级宝石才能合成2级宝石). 这时候zzx问city说“我要合成A级宝石需要多少 ...