阻塞式简易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也安 ...
随机推荐
- cupp字典生成器使用
下载: clone git https://github.com/Mebus/cupp.git
- js实现多级复选框的交互
功能介绍 整个复选框是包含多级,可能有父级,可能有子级,在勾选复选框时,要做两种判断: 1要判断它下面有没有子级,有子级将子级的选中状态checked变得和自己一样. 2要判断它是否有父级,有父级 ...
- sqlserver 数据库迁移
参考 https://blog.csdn.net/wuzhanwen/article/details/77449229 一.连接本地数据库引擎 新建一个数据库,如:rbrbsoft 二.连接远程数据库 ...
- oracle存储过程与存储函数的区别和联系
相同点:1.创建语法结构相似,都可以携带多个传入参数和传出参数. 2.都是一次编译,多次执行. 不同点:1.存储过程定义关键字用procedure,函数定义用function. 2.存储过程 ...
- python基础入门学习简单程序练习
1.简单的乘法程序 i = 256*256 print('The value of i is', i) 运行结果: The value of i is 65536 2.执行python脚本的两种方式 ...
- pta l3-3(社交集群)
题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805053141925888 题意:给定n个人,以及每个人的兴趣 ...
- centos 7 下 cobbler 安装
一.cobbler 介绍: Cobbler 是一个系统启动服务(boot server),可以通过网络启动(PXE)的方式用来快速安装.重装物理服务器和虚拟机,支持安装不同的 Linux 发行版和 W ...
- Shc 应用
1.说明 shc是一个加密shell脚本的工具, 它的作用是把shell脚本转换为一个可执行的二进制文件 2.安装 下载 # mget http://www.datsi.fi.upm.es/~fro ...
- 152. Maximum Product Subarray (Array; DP)
Find the contiguous subarray within an array (containing at least one number) which has the largest ...
- PHP文件上传与下载
一:上传文件与报错 $_FILES 超全局数组,包含了有关上传文件的所有信息! 而且,这个数组中只包含文件相关信息,其他数据依然在$_POST里面$_FILES是一个二维数组,每上传一个文件,都是数组 ...