使用Netty实现的一个简单HTTP服务器
1.HttpServer,Http服务启动类,用于初始化各种线程和通道
public class HttpServer {
public void bind(int port) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new HttpChannelInitService()).option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true); ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
} public static void main(String[] args) throws Exception {
int port = 8080;
if (args != null && args.length > 0) {
try {
port = Integer.valueOf(args[0]);
} catch (NumberFormatException e) { }
}
new HttpServer().bind(port);
}
}
2.HttpChannelInitService,通道初始化类
public class HttpChannelInitService extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel sc)
throws Exception {
sc.pipeline().addLast(new HttpResponseEncoder()); sc.pipeline().addLast(new HttpRequestDecoder()); sc.pipeline().addLast(new HttpChannelHandler());
} }
3.HttpChannelHandler,处理请求的HTTP信息
public class HttpChannelHandler extends ChannelInboundHandlerAdapter { private HttpRequest request = null;
private FullHttpResponse response = null; @Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
if (msg instanceof HttpRequest) {
request = (HttpRequest) msg;
String uri = request.getUri();
String res = "";
try {
res = ReadUtils.readFile(uri.substring(1));
response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK, Unpooled.wrappedBuffer(res.getBytes("UTF-8")));
setJsessionId(isHasJsessionId());
setHeaders(response);
} catch (Exception e) {//处理出错,返回错误信息
res = "<html><body>Server Error</body></html>";
response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,HttpResponseStatus.OK, Unpooled.wrappedBuffer(res.getBytes("UTF-8")));
setHeaders(response); }
if(response!=null)
ctx.write(response);
}
if (msg instanceof HttpContent) {
HttpContent content = (HttpContent) msg;
ByteBuf buf = content.content();
System.out.println(buf.toString(CharsetUtil.UTF_8));
buf.release();
}
}
/**
* 设置HTTP返回头信息
*/
private void setHeaders(FullHttpResponse response) {
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/html");
response.headers().set(HttpHeaders.Names.CONTENT_LANGUAGE, response.content().readableBytes());
if (HttpHeaders.isKeepAlive(request)) {
response.headers().set(HttpHeaders.Names.CONNECTION, Values.KEEP_ALIVE);
}
}
/**
* 设置JSESSIONID
*/
private void setJsessionId(boolean isHasJsessionId) {
if(!isHasJsessionId){
CookieEncoder encoder = new CookieEncoder(true);
encoder.addCookie(HttpSession.SESSIONID, HttpSessionManager.getSessionId());
String encodedCookie = encoder.encode();
response.headers().set(HttpHeaders.Names.SET_COOKIE, encodedCookie);
}
} /**
* 从cookie中获取JSESSIONID信息
* 判断服务器是否有客户端的JSESSIONID
* @author yangsong
* @date 2015年3月26日 下午2:08:07
*/
private boolean isHasJsessionId() {
try {
String cookieStr = request.headers().get("Cookie");
Set<Cookie> cookies = CookieDecoder.decode(cookieStr);
Iterator<Cookie> it = cookies.iterator(); while(it.hasNext()){
Cookie cookie = it.next();
if(cookie.getName().equals(HttpSession.SESSIONID)){
if(HttpSessionManager.isHasJsessionId(cookie.getValue())){
return true;
}
System.out.println("JSESSIONID:"+cookie.getValue()); }
}
} catch (Exception e1) {
e1.printStackTrace();
}
return false;
} @Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
System.out.println("server channelReadComplete..");
ctx.flush();//刷新后才将数据发出到SocketChannel
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
System.out.println("server exceptionCaught..");
ctx.close();
}
}
5.HttpSessionManager,Session管理类
/**
* HttpSession管理器
*/
public class HttpSessionManager { private static final HashMap<String,HttpSession> sessionMap = new HashMap<String, HttpSession>(); /**
* 创建一个session并返回sessionId
*/
public static String getSessionId(){
synchronized (sessionMap) {
HttpSession httpSession = new HttpSession();
sessionMap.put(httpSession.getSessionID(), httpSession);
return httpSession.getSessionID();
}
}
/**
* 判断服务器是否包含该客户端的session信息
*/
public static boolean isHasJsessionId(String sessiondId){
synchronized (sessionMap) {
return sessionMap.containsKey(sessiondId);
}
} }
6.页面信息与cookie
使用Netty实现的一个简单HTTP服务器的更多相关文章
- 用nodejs搭建一个简单的服务器
使用nodejs搭建一个简单的服务器 nodejs优点:性能高(读写文件) 数据操作能力强 官网:www.nodejs.org 验证是否安装成功:cmd命令行中输入node -v 如果显示版本号表示安 ...
- 初学Node(六)搭建一个简单的服务器
搭建一个简单的服务器 通过下面的代码可以搭建一个简单的服务器: var http = require("http"); http.createServer(function(req ...
- 轻松创建nodejs服务器(1):一个简单nodejs服务器例子
这篇文章主要介绍了一个简单nodejs服务器例子,本文实现了一个简单的hello world例子,并展示如何运行这个服务器,需要的朋友可以参考下 我们先来实现一个简单的例子,hello world ...
- Node学习(二) --使用http和fs模块实现一个简单的服务器
1.创建一个www目录,存储静态文件1.html.1.jpg. * html文件内容如下: 12345678910111213 <html lang="en">< ...
- Express 的基本使用(创建一个简单的服务器)
Express 的基本使用(创建一个简单的服务器) const express = require('express') // 创建服务器应用程序 // 相当于 http.creatServer co ...
- Netty练手项目-简单Http服务器
简单的设计思路就是,启动一个可以截断并处理Http请求的服务器代码.使用netty提供的boss线程与worker线程的模型,并使用netty的http解码器.自行编写了http url处理的部分.在 ...
- 理解与模拟一个简单web服务器
先简单说下几个概念,根据自己的理解,不正确请见谅. web服务器 首先要知道什么是web服务器,简单说web服务器就是可以使用HTTP传输协议与客户端进行通信的服务器.最初的web服务器只能用来处理静 ...
- Linux:写一个简单的服务器
开始了新篇章:Linux网络编程. 基础知识: 套接字概念 Socket本身有"插座"的意思,在Linux环境下,用于表示进程间网络通信的特殊文件类型.本质为内核借助缓冲区形成的伪 ...
- Windows 上静态编译 Libevent 2.0.10 并实现一个简单 HTTP 服务器(无数截图)
[文章作者:张宴 本文版本:v1.0 最后修改:2011.03.30 转载请注明原文链接:http://blog.s135.com/libevent_windows/] 本文介绍了如何在 Window ...
随机推荐
- emacs 简记
简介 Emacs作为神的编辑器,不用介绍了吧,说点感受. 用了一段时间了,总体感觉其实Emacs是很简单的,甚至比vim还简单,因为在X环境下,打开后可以就像记事本一样使用.但是,使用Emacs的人一 ...
- charles 4.x 破解版安装 以及使用
下载地址 https://pan.baidu.com/s/1dFvYM7B 破解方法 未破解的情况下,每30分钟会弹出一个提示,然后关闭软件 将压缩包内的 charles.jar 复制到安装目录下,替 ...
- 14、AppWidget及Launcher RemoteViews
一.Launcher的简单研究 1 什么是Launcher Android系统启动后加载的第一个程序 . 这个程序是其他应用程序的入口 . Launcher构成: HomeScreen : (Work ...
- python编程基础:《http://www.cnblogs.com/wiki-royzhang/category/466416.html》
windows自动化 http://www.cnblogs.com/wiki-royzhang/category/466416.html
- 【BZOJ3671】[Noi2014]随机数生成器 暴力
[BZOJ3535][Noi2014]随机数生成器 Description Input 第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子.第2行包含三个 ...
- 2017-2018-1 20179209《Linux内核原理与分析》第三周作业
一.函数调用堆栈 存储程序.函数调用堆栈(高级语言起点)和中断机制是计算机工作的三大法宝.其中函数调用堆栈是本次学习的重点.先介绍一些基本的知识点: 1.ebp 在C语言中用作记录当前函数调用的基址: ...
- OCR光学字符识别--STN-OCR 测试
1.同文章中建议的使用ubuntu-python隔离环境,真的很好用 参照:http://blog.topspeedsnail.com/archives/5618启动虚拟环境:source env/b ...
- 关于SAP S4 HANA 的13个问题
SAP S/4HANA的路线图是怎样的?价格是多少?下一步还将添加哪些新模块?莫不闻专业SAP问答平台结合SAP HANA及SAP HANA应用商务套件开发全球负责人Uwe Grigoleit帮大家整 ...
- Spring Aop切点
切点用于准确定位应该在什么地方应用切面的通知.通知和切点是切面的最基本的元素.在Spring AOP中要使用AspectJ的切点表达式来定义切点.下面我们列出Spring AOP所支持的AspectJ ...
- SQL语法之初级增删改查
SQL语法之初级增删改查 1.增 1.1插入单行 INSERT INTO [表名](列名) VALUES(列值) 语法如下: INSERT INTO bsp_Nproductclass(guid,pi ...