4

我使用了一些协议,并编写了自己的协议。我编写了一些只有 1 个字符的消息格式来识别消息,有些则使用 4 个字符。我觉得我没有足够的经验来判断哪个更好,所以我正在寻找一个答案来描述在哪种情况下一个可能比另一个更好。

出于性能考虑,您可以想象发送 2 个字节 ( A%1i) 比发送 5 个字节 ( ) 更快ABCD%1i。但是,我注意到,在编写带有 1 字节前缀的协议时,如果您有一个错误导致您的代码无法从套接字读取足够的数据,您可能会收到垃圾数据进入您的系统。

那么 4 字节前缀的目的仅仅是为了保证您的消息是干净的吗?你牺牲的性能值得吗?你真的会牺牲任何表现吗?也许最好有 2 或 3 个字节的前缀?

我不确定这个问题是否应该特定于 TCP,或者它是否适用于所有传输协议。这方面的建议会很有趣。

更新:出于兴趣,我会提到 Synergy 使用 4 字节消息前缀,因此对于鼠标移动增量,标题与实际数据大小相同。有些人建议只使用 1 或 2 个字节的前缀来提高效率。我想知道这会有什么缺点?

更新:另外,如果您担心垃圾数据,我想知道是否只有握手真的很重要。Synergy 的握手时间很长(几个字节),那么需要 4 字节的消息前缀吗?我最近制定了一个只有 1 字节握手的协议,结果证明这是一个坏主意,因为不兼容的协议正在向系统发送错误数据(在此之后,我可能建议至少有一个长握手) .

4

2 回答 2

1

标头的目的是为了更容易解决帧同步问题串行通信中的字节对齐)。为了同步,接收者在数据流中寻找任何“看起来像”消息开始头的东西。如果您有许多不同类型的有效消息开头标头,并且它们都是 1 字节长,那么您将不可避免地得到很多“错误帧同步”——来自“看起来”开头的垃圾-of-message 标头,但不是。最好选择一些其他标头,使其“不太可能”串行数据流中的任何内容“看起来”像一个有效的消息开头标头。

无论您如何设计数据包头,您都不可避免地会收到垃圾数据进入您的系统。无论您使用什么来处理这些其他问题(例如消息中间偶尔出现的位错误)也应该足以处理偶尔的“错误帧同步”垃圾。在某些系统中,任何坏数据都会很快被新的好数据覆盖,如果你眨眼,你可能永远看不到坏数据。其他系统至少需要在页脚中进行某种错误检测以拒绝不良数据。然而,其他系统不仅需要检测此类错误,还需要以某种方式不断重新发送该消息——直到双方都确信已成功接收到该消息的无错误版本。

正如 Oleksi 暗示的那样,在某些系统中,发送单个二进制位(100 毫秒)和发送 10 个字节(102.4 毫秒)之间的延迟没有显着差异。因此,与使用更详细的标头的优势(更容易调试;更容易实现向后兼容和前向兼容;更容易测试效果)相比,使用微小标头的优势(减少 2.4% 的延迟!)可能不值得“孤立地”进行微小更改,而无需将双方同步升级到与旧协议完全不兼容的新协议)。

也许您可以通过以下方式获得两全其美:(a)在很少使用的消息上保留冗长、易于调试的标头,以至于微小标头的影响太小而无法衡量(我怀疑几乎所有消息) ,以及 (b) 为任何类型的消息引入“微小标题”格式,其中微小标题的效果“明显更好”或至少可测量。看起来 Synergy 协议足够灵活,可以以一种很容易与其他类型的消息头区分开来的方式添加这种“微小的头”格式。

我在笔记本电脑和几台台式机之间使用Synergy 。我很高兴有人试图让它变得更好。

于 2012-07-24T18:36:34.353 回答
0

性能将取决于您发送的消息的内容。如果您的内容是几千字节,那么您的标头有多少字节并不重要。目前,我会选择最容易使用的方案,因为与您发送的实际数据相比,发送一个字节或四个字节之间的性能差异可以忽略不计。

于 2012-07-22T17:09:21.330 回答