java - 在 netty ChannelBuffer 中搜索字符串的最佳方法(无需创建新字符串)?

标签 java netty

我使用 Netty 实现了代理服务器,在其中解码 HTTP 请求,然后根据它们的路径将这些请求写入传出 channel 。我需要从 HTTP 请求的内容中提取一些信息以供将来处理(基本上,找到“request-id:”形式的子字符串并记录以供以后使用。执行此操作的最佳方法是什么?显然,我可以将 channel 缓冲区的内容转储到字符串中并使用标准的 java 字符串搜索技术,但是在 netty 中是否有一种简单且低开销的方法来执行此操作,而无需创建新字符串? ChannelBuffer 的 asCharSequence(CharSet) 方法,我可以只使用 java Pattern/Matcher。

最佳答案

不久前,当我试图嗅探 ChannelBuffer 中包含的字节的内容类型时,我遇到了这个问题。

我想到你可能会使用:

channelBuffer.toByteBuffer().asCharBuffer()
然后您可以将其传递给正则表达式 Pattern.Matcher,因为这不会重新分配缓冲区,而只是被包装并重新表示,就像以前一样。但这不起作用,因为 CharBuffer 需要进行 Charset.decoded,这可能与将 ChannelBuffer 转换为字符串一样糟糕。

ChannelBufferIndexFinder 的问题之一是它在搜索一个特定字节时往往效果最好,而当您搜索一个字符串(或更基本上是长度> 1的字节数组)时,我无法让它按照我想要的方式工作。

我开始研究这个名为 ByteSequenceIndexFinder 的 ChannelBufferIndexFinder 实现。这有助于在 ChannelBuffer 中找到实际的字节序列,但它有几个问题:

  1. 因为路ChannelBuffer.bytesBefore(...)有效,它不会返回所定位数组的直接偏移量,而是返回其末尾,因此您必须从返回的索引中减去字节数组长度+1来获取该数组开头的偏移量字节缓冲区内的字节序列。
  2. 由于查找器必须保持状态(到目前为止匹配的字节数),因此它不是线程安全的。我尝试用 ThreadLocal 替换简单状态(一个 int),但性能大大降低,但它仍然是一种选择。

实际上有一种非标准的替代调用方法可以解决问题#1,其工作原理如下:

ChannelBuffer bufferToSearch = ...;
String searchStr = "....";
ByteSequenceIndexFinder finder = new ByteSequenceIndexFinder(searchStr.getBytes());
int startingOffset = finder.findIn(bufferToSearch);

startingOffset 是 channel 缓冲区中匹配字节序列的第一个字节的偏移量。

如果您需要这样的东西,希望它对您有所帮助。 This是它的测试用例的开始。

关于java - 在 netty ChannelBuffer 中搜索字符串的最佳方法(无需创建新字符串)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16306383/

相关文章:

java - 比较 Java 中的字符串 .equals()

java.awt.AWTError : BoxLayout can't be shared 错误

java - Netty 服务器到服务器的数据流

netty - 使用 Spring IoC 配置 Netty

java - 服务器使用 websocket 和 netty 发送问候消息 -> 导致异常

java - MIDI 程序警告

java - 如何使用android获取NFC标签中的完整数据?

java - 随机字符和随机颜色生成器

java - OIO在Java中是什么意思?

java - 何时在netty中使用Unpooled