消息字节——MessageBytes

在tomcat核心处理中有这么一个需求——“为了提高编码性能,对于socket接收到的字节流不马上进行某种编码的转码,而是应该保留字节流的形式,在需要时、在指定编码时才进行转码工作”。MessageBytes正是为解决这个问题而提出的一个类。

消息字节封装了不同类型方式用于表示信息,它包含了四种类型:T_BYTES、T_CHARS、T_STR、T_NULL,分别表示字节类型、字符类型、字符串类型、空。由于web服务器通信过程使用ASCII码通信,对应的是字节,所以这里选取T_BYTES类型作为案例说明,其他类型与之类似。消息字节的使用方法很简单,假如有一个字节数组byte[] buffer,它坐标的第3到第20之间的字节数组组成的字符表示Request对象中的方法变量的值,那么用以下代码简单表示:

①   public class Request{

MessageBytes methodMB = new MessageBytes();

 

public MessageBytes method() {

        returnmethodMB;

    }

}

②   Request request = new Request();

request.method().setBytes(buffer, 3, 18);

 

执行上面操作后就完成对字节数组的某段进行标记操作,方便以后获取指定的一段字节数组,参照下图,你可以用多个消息字节对buffer标记,例如对请求变量、协议版本等变量进行标记,每个消息字节实例标识了一段字节数组,可以通过如下获取并转为字符串类型:

request.method().toString();

 

使用起来很简单,接着看下实际实现原理,化繁为简,由于tomcat底层接收的是字节流,于是只考虑T_BYTES的情况。

①   MessageBytes类

public class MessageBytes {

         private finalByteChunk byteC = new ByteChunk();

 

         public voidsetBytes(byte[] b, int off, int len) {

                   byteC.setBytes(b,off, len);

         }

 

         public StringtoString() {

                   returnbyteC.toString();

         }

}

②   ByteChunk类

public class ByteChunk {

         privatebyte[] buff;

         private intstart = 0;

         private intend;

 

         public voidsetBytes(byte[] b, int off, int len) {

                   buff= b;

                   start= off;

                   end= start + len;

         }

 

         public StringtoString() {

                   Charsetcharset=Charset.forName("ISO_8859_1");

                   CharBuffercb = charset.decode(ByteBuffer.wrap(buff, start, end - start));

                   returnnew String(cb.array(), cb.arrayOffset(), cb.length());

         }

}

 

前面示例中methodMB.setBytes(buffer, 3, 18)其实是调用了ByteChunk的setBytes方法,把字节流及始末坐标设置好,后面methodMB.toString()同样调用了ByteChunk的toString方法,根据指定编码进行转码,这里是ISO_8859_1。这样一来就达到了延迟处理模式的效果,在需要时才根据指定编码转码并获取字符串,不需要的话则无需转,处理性能得到提高。

Tomcat对于socket接收的信息都用消息字节表示,好处是实现一种延迟处理模式,提高性能。而且实际上tomcat还引入了字符串缓存,在转码之前会先从缓存中查找是否有对应的编码的字符串,如果存在则不必再执行转码动作而直接返回对应的字符串,性能进一步得到优化。为了性能我们必须要多做一些额外的工作,这也是tomcat接收到的信息为何不直接用字符串String保存的原因。

点击订购作者《Tomcat内核设计剖析》

时间: 2024-07-31 22:23:39

消息字节——MessageBytes的相关文章

用Kerberos为J2ME应用程序上锁,第1部分

简介: 用户需要确保所使用的无线应用程序不会损害他们的敏感信息.其中一种方法就是使用行业标 准协议如 Kerberos 来提供安全性.在本系列中,Faheem Khan 将创建一个示例 J2ME MIDlet,它使用 Kerberos 来保护财务数据.本文是该系列的第一篇文章,他通过解释为他的应用程序的安全性提供骨架 的 Kerberos 数据格式,介绍了一些基本知识. 许多用户不愿意使用通过无线连接发送敏感数据的应用程序,因为他们不信任无线安全性.但是使传 统有线网络上的电子商务的安全成为可能

C++程序员Protocol Buffers基础指南

这篇教程提供了一个面向 C++ 程序员关于 protocol buffers 的基础介绍.通过创建一个简单的示例应用程序,它将向我们展示: 在 .proto 文件中定义消息格式 使用 protocol buffer 编译器 使用 C++ protocol buffer API 读写消息 这不是一个关于在 C++ 中使用 protocol buffers 的全面指南.要获取更详细的信息,请参考Protocol Buffer Language Guide 和 Encoding Reference.

C++ 程序员 Protocol Buffers 基础指南

这篇教程提供了一个面向 C++ 程序员关于 protocol buffers 的基础介绍.通过创建一个简单的示例应用程序,它将向我们展示: 在 .proto 文件中定义消息格式 使用 protocol buffer 编译器 使用 C++ protocol buffer API 读写消息 这不是一个关于在 C++ 中使用 protocol buffers 的全面指南.要获取更详细的信息,请参考 Protocol Buffer Language Guide 和 Encoding Reference.

深入Protobuf源码-概述、使用以及代码生成实现

概述 捣鼓hdfs.yarn.hbase.zookeeper的代码一年多了,是时候整理一下了.在hadoop (2.5.2)中protobuf是节点之间以及客户端和各个节点通信的基础序列化框架(协议),而基于avro和Writable的序列化框架则是这个协议里的payload,因而这一系列的文章打算从protobuf这个框架开始入手(版本2.5.0). 从抽象的角度来说,protobuf框架是类实例序列化和远程调用的一种实现.所谓实例序列化简单来说就是将一个类实例转换成字节数组或字节流来表达,这

Python 3: 加密简介

Python 3 的标准库中没多少用来解决加密的,不过却有用于处理哈希的库.在这里我们会对其进行一个简单的介绍,但重点会放在两个第三方的软件包:PyCrypto 和 cryptography 上.我们将学习如何使用这两个库,来加密和解密字符串. 哈希 如果需要用到安全哈希算法或是消息摘要算法,那么你可以使用标准库中的 hashlib 模块.这个模块包含了符合 FIPS(美国联邦信息处理标准)的安全哈希算法,包括 SHA1,SHA224,SHA256,SHA384,SHA512 以及 RSA 的

开源日志库Logger的剖析

库的整体架构图 详细剖析 我们从使用的角度来对Logger库抽茧剥丝: String userName = "Jerry";  Logger.i(userName);   看看Logger.i()这个方法: public static void i(String message, Object... args) {            printer.i(message, args);  }   还有个可变参数,来看看printer.i(message, args)是啥: publi

《KAFKA官方文档》设计与实现(二)

5.4 消息格式 /** * 1. 消息的4字节CRC32 * 2. 一个字节的 identifier ,用以格式的变化,变化的值为0 或者1 * 3. 一个字节的 identifier属性,允许消息的注释与版本无关 * 位 0 ~ 2 : 压缩编解码 * 0 : 无压缩 * 1 : gzip * 2 : snappy * 3 : lz4 * bit 3 : 时间戳类型 * 0 : 创建时间 * 1 : 日志追加时间 * bit 4 ~ 7 : 保留位 * 4. (可选的) 8字节时间戳只有当"

Java网络服务器(Mina架构)往C++网络服务器发送消息,掉1字节,请问是什么原因

问题描述 JAVAServer是以MINA为基础构建的网络通讯消息包现在有这么一个问题:以二进制的形式往C++服务器发送消息.我断点跟踪的情况是将:30-0-0-0-2-3-1-0-0-0-b-0-63-64-79-40-31-32-36-2e-63-6f-6d-18-0-0-0-3-1-5-0-31-30-30-38-39-3-0-63-64-79-4-0-6e-75-6c-6c-1-0-0-0推送到客户端,但是很根据抓包的情况来看,只有30-0-0-0-2-3-1-0-0-0-b-0-63-

socket服务端向客户端发送字节数组消息时客户端无法接收问题

问题描述 socket服务端向客户端发送字节数组消息时客户端无法接收问题