`
zeroliu
  • 浏览: 195176 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

NIO框架Cindy中HTTP范例的一个BUG及修改

阅读更多
由于工作原因,想采用NIO技术,研究了一下CrmkyCindy框架。由于使用长连接方式,数据协议采用定长包头+不定长保体的方式,因而主要研究了其中的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;
	}
分享到:
评论

相关推荐

    开源nio框架cindy源码

    Cindy是一款基于Java NIO(Non-blocking Input/Output)的开源...通过深入研究Cindy源码,开发者不仅可以学习到NIO的高级用法,还能了解到如何设计和实现一个高性能的网络通信框架,这对于提升个人技术能力非常有帮助。

    Java_NIO框架Netty教程

    资源名称:Java_NIO框架Netty教程资源截图: 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。

    基于Groovy的NIO框架,仅供学习Java NIO使用。.zip

    Java NIO(New IO)是Java 1.4版本引入的一个新特性,它提供了一种不同于传统IO(-blocking I/O)的I/O操作方式。传统的IO模型是基于流的,通常涉及阻塞式读写,而NIO则引入了通道(Channels)和缓冲区(Buffers)的...

    Java NIO通信框架在电信领域的实践

    电信软件是一个宽泛的概念,根据功能和应用场景的不同大致可以分为两大类:系统软件和业务应用软件。系统软件通常涉及底层技术和基础设施,如路由器中的信令机软件和移动设备的操作系统等。而业务应用软件则更侧重于...

    NIO通信框架

    NIO通信框架 网络 通信 类 收集的资料 java 可以使用

    xsocket NIO框架示例

    xsocket NIO框架示例 resources 中有相关的 资料。telnet服务测试教程。和相关jar

    基于java的开发源码-NIO网络框架 xSocket.zip

    基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络框架 xSocket.zip 基于java的开发源码-NIO网络...

    httpcore-nio-4.3.jar包

    Apache HttpComponents项目中的HttpCore NIO模块(httpcore-nio)就是这样一个框架,它提供了基于Java NIO(New IO)的非阻塞I/O支持,极大地提升了网络应用的性能和并发能力。本文将详细探讨HttpCore NIO 4.3版本的...

    NIO框架Netty实现高性能高并发

    最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨 节点远程服务调用。相比于传统基于Java序列化+BIO(同步阻塞IO)的通信框架,性能提升...

    Java_NIO框架Netty教程.pdf

    Netty是基于Java NIO构建的一个高性能、异步事件驱动的网络应用程序框架,它极大地简化了网络编程,特别是TCP和UDP套接字服务的开发。 Netty的特点: 1. **高度可定制化**:Netty允许开发者自定义各种协议编解码器...

    Java springboot 整合mina 框架,nio通讯基础教程,mina框架基础教程.zip

    Mina框架是一个轻量级的网络通信框架,基于Java NIO构建,它简化了网络编程的复杂性,提供了高效的I/O处理能力。Mina支持多种协议,如TCP、UDP等,适用于开发服务器端和客户端应用。Mina的核心组件包括IoSession...

    基于NIO框架的TeeTime信息平台的设计与实现

    NIO中引入了通道(Channel)、缓冲区(Buffer)和选择器(Selector)等关键概念,其中缓冲区是一个数据容器,用于存储数据的数组和控制数据读写的属性组成。通道则是数据传输的路径,选择器则是多个通道对象的多路...

    基于java的异步IO框架 Cindy.zip

    Cindy是一个基于Java实现的异步IO框架,旨在简化多路复用I/O和事件驱动编程的复杂性。下面我们将深入探讨Java异步IO的基本概念、Cindy框架的特点以及如何使用Cindy进行实际开发。 首先,理解Java中的异步I/O。在...

    NIO简易服务器框架、文件传输

    在本文中,我们将深入探讨如何使用Java的非阻塞I/O(NIO)技术构建一个简易的服务器框架,以及在此框架下实现文件的传输。NIO(New Input/Output)是Java提供的一种I/O模型,它与传统的阻塞I/O(BIO)不同,能够以更...

    netty 新NIO框架 文档

    Netty作为一个先进的网络框架,不仅解决了传统网络编程中的许多痛点,还提供了丰富的高级特性,使得开发者可以专注于业务逻辑而不用担心底层细节。无论是构建高性能的服务端应用还是处理复杂的网络协议,Netty都是一...

    基于Java的实例源码-异步IO框架 Cindy.zip

    Cindy是一个用于Java的异步IO框架,旨在简化并发编程并优化性能。这个压缩包"基于Java的实例源码-异步IO框架 Cindy.zip"提供了Cindy框架的具体实现,对于学习和理解Java异步I/O有极大的帮助。 1. **Java NIO基础**...

    基于Java的异步IO框架 Cindy.zip

    Cindy是一个这样的框架,它旨在简化Java中的异步编程模型,提供更好的性能和可扩展性。让我们深入探讨Cindy框架以及Java异步I/O的相关知识点。 ### 1. Java的异步I/O模型 在传统的Java I/O模型中,如BIO(Blocking...

    Ioserver java Nio socket 框架

    Ioserver java Nio socket 框架 是个不错的NIO 通讯框架,本来想学习mina框架,看了看mina的源码太头痛,本人觉得看懂了Ioserver 再看mina的框架,想多的学习 java NIO 的也可以下载 看看,很值得学习啊!!!

    java源码:异步IO框架 Cindy.rar

    本篇文章将深入探讨Java中的异步IO框架Cindy,揭示其设计原理、核心组件以及如何在实际项目中应用。 首先,我们来理解一下什么是异步I/O。与传统的同步I/O模式不同,异步I/O不会在等待数据读写完成时阻塞线程,而是...

Global site tag (gtag.js) - Google Analytics