由于工作原因,想采用NIO技术,研究了一下
Crmky的
Cindy框架。由于使用长连接方式,数据协议采用定长包头+不定长保体的方式,因而主要研究了其中的HTTP范例。在net.sf.cindy.example.http的HttpRequestDecoder中,发现了一个BUG。原始代码如下:
public Object decode(Session session, Packet packet) throws Exception {
Buffer buffer = packet.getContent();
int index = buffer.indexOf(TOKEN);
if (index >= 0) {
String[] headers = buffer.getString(Charset.UTF8,
index + TOKEN.length).split("\r\n");
HttpRequest request = new HttpRequest();
parse(request, headers);
String contentLen = request.getParam("Content-Length");
if (contentLen != null) {
int len = Integer.parseInt(contentLen);
if (buffer.remaining() >= len) {
byte[] content = new byte[len];
buffer.get(content);
request.setContent(content);
} else {
return null;
}
}
return request;
}
return null;
}
假设:
第一步:http头已经读完,但http报文体长度不够,此时return null,等待下次读取;
第二步:在第二次下次读取时候http报文体时,又会重新检查TOKEN(\r\n\r\n),此时(index>=0)返回false,直接return null了。
此时,不能不确读取HTTP报文。其实,Cindy的接口中,定义了Attributes相关操作,因而可以把第一次读取的内容,通过session.setAttribute(HTTP_HEAD, request)缓存起来,下次读取是再继续。通过检查HTTP_HEAD的attribute是否存在,来绝对读取报文头还是报文体。修改后的代码如下:
public Object decode(Session session, Packet packet) throws Exception {
Buffer buffer = packet.getContent();
final String HTTP_HEAD = null;
Object request_obj = session.getAttribute(HTTP_HEAD);
HttpRequest request_inst = null;
if (request_obj==null) { //读取HTTP头
int index = buffer.indexOf(TOKEN);
if (index >= 0) {
String[] headers = buffer.getString(Charset.UTF8,
index + TOKEN.length).split("\r\n");
request_inst = new HttpRequest();
parse(request_inst, headers);
}else return null; //读取HTTP头不完整,留到下次读取;
}else { //上次已经读取了HTTP头,本次只读HTTP报文体
request_inst = (HttpRequest)request_obj;
}
String bodylen_str = request_inst.getParam("Content-Length");
if (bodylen_str!=null || (! "0".equals(bodylen_str))) {
int bodylen_int = Integer.parseInt(bodylen_str);
if (buffer.remaining() >= bodylen_int) {
byte[] content = new byte[bodylen_int];
buffer.get(content);
request_inst.setContent(content);
} else {
return null; //等待下次再继续读取
}
}
//完整读取了一个HTTP报文(可能BodyLen==0)
session.removeAttribute(HTTP_HEAD);
return request_inst;
}
分享到:
- 2006-11-13 11:21
- 浏览 3430
- 评论(0)
- 论坛回复 / 浏览 (0 / 4041)
- 查看更多
相关推荐
开源nio框架cindy,cindy-3.0b1-src
资源名称:Java_NIO框架Netty教程资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
基于Groovy的NIO框架,仅供学习Java NIO使用。
常见NIO开源框架(MINA、xSocket)学习 基于io包的阻塞式socket通信代码简单,在连接数很少的情况下是一个不错的选择。不过实际应用中一个socket服务器采用传统的阻塞式socket方式通信可能会是一场灾难,一路...
从广义上看电信软件的范围非常广,细分实际可以分为两大类:系统软件和业务应用软件。...本文重点介绍电信业务应用软件的技术变迁历史,以及华为电信软件架构演进和Java NIO框架在技术变迁中起到的关键作用。
NIO通信框架 网络 通信 类 收集的资料 java 可以使用
xsocket NIO框架示例 resources 中有相关的 资料。telnet服务测试教程。和相关jar
基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络...
最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨 节点远程服务调用。相比于传统基于Java序列化+BIO(同步阻塞IO)的通信框架,性能提升...
介绍JavaNIO框架netty的特点和如何使用等,可以多多学习。
netty 新NIO框架 文档,在jetty项目中用到了该框架。 netty更注重IO读写,效率很高。更支持servlet1.0异步的websocket。值得一看
Ioserver java Nio socket 框架 是个不错的NIO 通讯框架,本来想学习mina框架,看了看mina的源码太头痛,本人觉得看懂了Ioserver 再看mina的框架,想多的学习 java NIO 的也可以下载 看看,很值得学习啊!!!
Java NIO框架Netty教程 很好的东西!
它是一个基于 NIO 框架 Netty 的 HTTP 服务器,提供处理 HTTP 请求并将有关它们的信息存储在数据库中。 在默认服务器有下一个处理程序: - 提供有用的服务器初始化和一些配置。 - 处理 HTTP 请求并基于该构造响应...
基于NIO框架的TeeTime信息平台的设计与实现,是一篇不错的论文,NIO框架的具体应用。
NIO网络框架 xSocket
NIO 框架 netty 与 mina
基于NIO的远程调用框架的设计与实现 master
Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...