- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我为一个小型多人游戏实现了一个协议(protocol)。它基于字节,因此要反序列化接收到的消息,我必须遍历字节流并逐位解析它。在拥有所有字节并知道消息类型之后,我将字节扔到反向构造器中,该构造器从原始字节构造协议(protocol)数据单元。
整个过程非常丑陋,不是真正的面向对象,并且具有不可读的if/else代码。
我必须为添加的每个协议(protocol)数据单元(pdu)实现reverseConstructor(byte[] bytes)
。每个pdu都定义某种模式的方法(例如,模式= [1字节int(id = x),x字节ascii字符串,4字节 double 数]),并且使用该模式对字节进行处理更优雅。
我在这里有关于使用Google的protobuf的提示(显然,它们不符合我的需求,因为我必须更改协议(protocol)以遵守protobuf标准)。
信息
我无法更改协议(protocol)。有和两种不同的方案(我不想希望同时甚至在同一程序中支持它们):
while (true) {
if (buffer.remaining() < frameLength) {
buffer.reset();
break;
}
if (frameLength > 0) {
Object resultObj = prototype.newBuilderForType().mergeFrom(buffer.array(), buffer.arrayOffset() + buffer.position(), frameLength).build();
client.fireMessageReceived(resultObj);
buffer.position(buffer.position() + frameLength);
buffer.mark();
}
if (buffer.remaining() > fieldSize) {
frameLength = getFrameLength(buffer);
} else {
break;
}
}
Parse data as a message of this type and merge it with the message being built. This is just a small wrapper around MessageLite.Builder.mergeFrom(CodedInputStream). https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/Message.Builder#mergeFrom(byte[])
最佳答案
1.协议(protocol)设计
坦白说,创建第一个协议(protocol)实现而没有任何进一步的改变是一个常见的错误。作为练习,让我们尝试设计灵活的协议(protocol)。
基本上,这个想法是将多个帧彼此封装在一起。请注意,您可以使用有效负载ID ,因此很容易识别序列中的下一帧。
您可以使用Wireshark来查看现实生活中的协议(protocol)通常遵循相同的原理。
这种方法大大简化了数据包的剖析,但是仍然可以处理其他协议(protocol)。
2.协议(protocol)解码(解剖)
我花了很多时间为以前的公司开发下一代网络分析仪。
无法透露所有细节,但是关键功能之一是灵活的协议(protocol)栈,能够识别协议(protocol)框架。 RTP是一个很好的例子,因为在较低层(通常是UDP)上没有任何提示,下一帧是RTP帧。开发了特殊虚拟机来执行解剖器和控制过程。
好消息是我的小型个人项目带有基于Java的解剖器(为了节省多行,我将跳过一些javadocs)。
/**
* High-level dissector contract definition. Dissector is meant to be a simple
* protocol decoder, which analyzes protocol binary image and produces number
* of fields.
*
* @author Renat.Gilmanov
*/
public interface Dissector {
/**
* Returns dissector type.
*/
DissectorType getType();
/**
* Verifies packet data belongs to the protocol represented by this dissector.
*/
boolean isProtocol(DataInput input, Dissection dissection);
/**
* Performs the dissection.
*/
Dissection dissect(DataInput input, Dissection dissection);
/**
* Returns a protocol which corresponds to the current dissector.
*
* @return a protocol instance
*/
Protocol getProtocol();
}
public interface Protocol {
// ...
List<Protocol> getUpperProtocols(); }
/**
* Verifies current frame belongs to RTP protocol.
*
* @param input data input
* @param dissection initial dissection
* @return true if protocol frame is RTP
*/
@Override
public final boolean isProtocol(final DataInput input, final Dissection dissection) {
int available = input.available();
byte octet = input.getByte();
byte version = getVersion(octet);
byte octet2 = input.getByte(1);
byte pt = (byte) (octet2 & 0x7F);
return ((pt < 0x47) & (RTP_VERSION == version));
}
// --- protocol header --------------------------------
final byte octet1 = input.getByte(0);
final byte version = getVersion(octet1);
final byte p = (byte) ((octet1 & 0x20) >> 5);
final byte x = (byte) ((octet1 & 0x10) >> 4);
final byte cc = (byte) ((octet1 & 0x0F));
//...
// --- seq --------------------------------------------
final int seq = (input.getInt() & 0x0000FFFF);
final int timestamp = input.getInt();
final int ssrc = input.getInt();
public interface ProtocolStack {
String getName();
Protocol getRootProtocol();
Dissection dissect(DataInput input, Dissection dissection, DissectOptions options);
}
Abstract Syntax Notation One (ASN.1) is a standard and notation that describes rules and structures for representing, encoding, transmitting, and decoding data in telecommunications and computer networking. The formal rules enable representation of objects that are independent of machine-specific encoding techniques. Formal notation makes it possible to automate the task of validating whether a specific instance of data representation abides by the specifications. In other words, software tools can be used for the validation.
FooProtocol DEFINITIONS ::= BEGIN
FooQuestion ::= SEQUENCE {
trackingNumber INTEGER,
question IA5String
}
FooAnswer ::= SEQUENCE {
questionNumber INTEGER,
answer BOOLEAN
}
END
JAC (Java Asn1 Compiler) is a tool for you if you want to (1)parse your asn1 file (2)create .java classes and (3)encode/decode instances of your classes. Just forget all asn1 byte streams, and take the advantage of OOP! BER, CER and DER are all supported.
This class takes care of converting the entries to/from TupleInput and TupleOutput objects. Its two abstract methods must be implemented by a concrete subclass to convert between tuples and key or data objects.
entryToObject(TupleInput)
objectToEntry(Object,TupleOutput)
Version: byte (2 bits)
Padding: bool (1 bit)
Extension: bool (1 bit)
CSRC Count: byte (4 bits)
Marker: bool (1 bit)
Payload Type: byte (7 bits)
Sequence Number: int (16 bits)
class Clock extends Struct { // Hardware clock mapped to memory.
Unsigned16 seconds = new Unsigned16(5); // unsigned short seconds:5 bits
Unsigned16 minutes = new Unsigned16(5); // unsigned short minutes:5 bits
Unsigned16 hours = new Unsigned16(4); // unsigned short hours:4 bits
...
}
关于java - 字节流中协议(protocol)数据单元的动态识别和处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18270311/
我想执行一堆 WebRequest,但设置了可以同时启动的阈值。 我遇到了这个LimitedConcurrencyTaskScheduler example并尝试像这样使用它 scheduler =
初始情况 我正在开发 .NET Framework 4.0、C#、Winform 应用程序。应用程序将在 GridView 中列出(并测试)WebServiceOperations(目前有 60 个
我有一个具有 5 个读取和 5 个写入容量的发电机表。在这张表中,我有两条记录。 然后我决定通过一次推送大量写入(一次突发大约 4000 条记录)看看我会得到什么样的错误响应。蓝色的“已消耗”线直接越
我在限制作业和“挂起”或“失败”的作业方面遇到了麻烦。这基本上就是我正在尝试做的事情。 $allServers = Import-Csv "C:\temp\input.csv" $job = $all
我正在编写一个运行微 Controller 仿真器的C++程序。运行模拟器的线程在这样的循环中这样做: while(should_run) { simulator->RunSingleClockC
我有这个简单的代码,它: 创建 IObservable 采样半秒 使用 ThreadPool 调度程序订阅它 使用 SynchronizationContext 观察它 代码如下: private v
我正在尝试翻译一些 C# 代码,它一次创建 N 个线程并在每个线程中运行一个函数。 我有两个问题: -如何限制一次N个线程? -当我在我的主要方法中引用静态整数 FastestMemory 和 Slo
我有一个splitpane我的 React 项目中的组件,在调整 Pane 大小时将对其宽度使用react并更改内容。拆分 Pane 组件具有以下事件监听器... componentDidMo
使用 urllib2 时是否可以轻松限制 kbps?如果是,如果您能指导我使用任何代码示例或资源,我们将不胜感激。 最佳答案 urllib 模块中有urlretrieve(url, filename=
使用 urllib2 时是否可以轻松限制 kbps?如果是,如果您能指导我使用任何代码示例或资源,我们将不胜感激。 最佳答案 urllib 模块中有urlretrieve(url, filename=
我正在为 Android Phone 构建应用程序,但遇到了一些奇怪的“节流”。我相信这是因为正在调用信号量来停止应用程序正在做的任何事情来处理手机中的其他内容。虽然我不是积极的。 我很好奇是否有一种
我使用 Charles (4.0.2) 作为代理服务器来测试我的移动应用程序,它依赖于 WKWebView 内部的 WebSockets。我正在尝试模拟一种情况,在这种情况下,用户会短暂地体验到他们的
我有一个 request-promise向 API 发出请求的函数。我受此 API 的速率限制,并且不断收到错误消息: Exceeded 2 calls per second for api clie
我正在使用网络服务发送 100 个 http 帖子。但是,该服务每秒只允许 5 个。我想知道 usleep 命令是否是执行此操作的最佳方法。例如: foreach($JSONarray['DATABA
我在随机时间以高频率接收数据对象,并且需要使用这些更新 JavaFX GUI。但是,我不想用大量的可运行对象填充 javafx 事件队列(我使用 Platform.RunLater)。 我一直在思考如
假设我有一个即时消息应用程序,每次收到消息时它都会发出哔声。我想 debounce 哔哔声,但我想在第一条消息到达时播放哔哔声,而不是为后续消息播放(在时间跨度内,比如 2 秒)。 另一个示例可能是:
所以我现在有: App.html import { debounce } from 'lodash' export default { data () { na
我将 Highstock.js 更新到 1.3 并注意到 afterSetExtemes 事件在每次拖动事件时触发,而不是 dragend/mouseup。我正在通过 ajax 更新主要系列,但现在这
我已经在我的 pod 的所有容器上设置了 CPU 和 Memory Requests=Limits,以使其符合保证服务质量类的资格。现在,查看过去 6 小时同一 Pod 的这些 CPU 使用率和 CP
我将 Highstock.js 更新到 1.3 并注意到 afterSetExtemes 事件在每次拖动事件时触发,而不是 dragend/mouseup。我正在通过 ajax 更新主要系列,但现在这
我是一名优秀的程序员,十分优秀!