二进制协议与文本协议

有人对二进制协议有一个很好的定义吗?短信协议到底是什么?它们之间的比特数比较起来怎么样?

以下是维基百科对二进制协议的解释:

二进制协议是一种预期由机器而不是人来读取的协议(http://en.wikipedia.org/wiki/Binary_protocol)

哦,拜托!

更清楚地说,如果我有 jpg 文件,它将如何通过二进制协议发送,以及如何通过一个文本?当然是以电线上发送的比特/字节来表示。

在一天结束的时候,如果你看一个字符串,它本身就是一个字节数组,所以两个协议之间的区别应该取决于在线路上发送的实际数据。换句话说,就是在发送之前如何对初始数据(jpg 文件)进行编码。

50992 次浏览

I think you got it wrong. 并不是协议决定了数据在“线路”上的外观,而是数据类型决定了使用哪种协议来传输数据。 以 tcp 套接字为例,一个 jpeg 文件将用二进制协议发送和接收,因为它是二进制数据(不是人类可读的,字节在32-126 ascii 范围内) ,但是你可以发送/recv 文本文件与两种协议,你不会注意到差异。

两者使用不同的字符集,文本一个,使用一个简化的字符集,二进制包括所有它能,不仅“字母”和“数字”,(这就是为什么维基百科说“人类”)

更清楚的是,如果我有 jpg 文件,它将如何通过一个二进制协议发送,如何 > 通过一个文本?当然是以电线上发送的比特/字节来表示。

你应该读读这本 基地64

如果你有任何意见,我都很感激,我只是想了解事情的本质。

我认为缩小字符集的本质,就是缩小复杂性,达到可移植性、兼容性。很难安排和同意很多人去尊重一个宽字符集,(或者一个宽的任何东西)。拉丁/罗马字母和阿拉伯数字是世界闻名的。(当然还有其他考虑因素来减少代码,但这是一个主要的考虑因素)

假设在二进制协议中,各部分之间的“契约”是关于比特的,第一个比特指的是这个,第二个比特指的是那个,等等。或者甚至是字节(但是可以自由使用字符集而不必考虑便携性) ,例如在私有封闭系统或(接近硬件标准) ,但是如果你设计一个开放系统,你必须考虑你的代码在广泛的情况下如何表示,例如它将如何在世界另一端的机器上表示?因此,这里来的文本协议,其中的合同将尽可能标准化。我设计了这两种方案,这就是原因,二进制的非常自定义的解决方案和文本的开放或/和便携式系统。

二进制协议和文本协议实际上并不是关于二进制斑点是如何编码的。区别实际上在于协议是面向数据结构还是面向文本字符串。让我举个例子: HTTP。HTTP 是一个文本协议,即使当它发送一个 jpeg 图像时,它只发送原始字节,而不是它们的文本编码。

但是使 HTTP 成为一个文本协议的是到 走开的交换 jpg 看起来像这样:

要求:

GET /files/image.jpg HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/4.01 [en] (Win95; I)
Host: hal.etc.com.au
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8

回应:

HTTP/1.1 200 OK
Date: Mon, 19 Jan 1998 03:52:51 GMT
Server: Apache/1.2.4
Last-Modified: Wed, 08 Oct 1997 04:15:24 GMT
ETag: "61a85-17c3-343b08dc"
Content-Length: 60830
Accept-Ranges: bytes
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: image/jpeg


<binary data goes here>

请注意,这可以很容易地被更紧密地包装到一个结构中,看起来(在 C 中)类似于

要求:

struct request {
int requestType;
int protocolVersion;
char path[1024];
char user_agent[1024];
char host[1024];
long int accept_bitmask;
long int language_bitmask;
long int charset_bitmask;
};

回应:

struct response {
int responseType;
int protocolVersion;
time_t date;
char host[1024];
time_t modification_date;
char etag[1024];
size_t content_length;
int keepalive_timeout;
int keepalive_max;
int connection_type;
char content_type[1024];
char data[];
};

其中字段名称根本不需要传输,例如,响应结构中的 responseType是一个值为200的 int,而不是三个字符“2’0’0’”。这就是基于文本的协议: 它被设计成一个平面的文本流(通常是人类可读的) ,而不是许多不同类型的结构化数据。

二进制协议的示例: RTPTCPIP

文本协议示例: SMTPHTTPSIP

这应该允许您概括二进制和文本协议的合理定义。

提示: 直接跳到示例部分或图表。它们用来说明 泰勒的回答很棒

这里有一个类似于逃避的定义:

你看到就知道了。

这是很难找到涵盖所有角落情况的简明定义的情况之一。但它也是那些角落案例完全不相关的情况之一,因为它们根本不会在现实生活中发生。

在现实生活中遇到的几乎所有协议要么是这样的:

> fg,m4wr76389b zhjsfg gsidf7t5e89wriuotu nbsdfgizs89567sfghlkf
>  b9er t8ß03q+459tw4t3490ß´5´3w459t srt üßodfasdfäasefsadfaüdfzjhzuk78987342
< mvclkdsfu93q45324äö53q4lötüpq34tasä#etr0 awe+s byf eart

[想象一吨其他非印刷废物在那里。传达文本和二进制文本之间差异的挑战之一是必须以文本形式传达:

或者像这样:

< HELLO server.example.com
> HELLO client.example.com
< GO
> GETFILE /foo.jpg
< Length: 3726
< Type: image/jpeg
< READY?
> GO
< ... server sends 3726 bytes of binary data ...
> ACK
> BYE

[I just made this up on the spot.]

这里没有那么多模棱两可的地方。

我有时听到的另一个定义是

文本协议是可以使用 telnet进行调试的协议

也许我在这里展示了我的书呆子气,但我 have实际上通过 SMTP 和 POP3写和读电子邮件,通过 NNTP 阅读用户网文章,通过 HTTP 浏览网页使用 telnet,没有其他原因,只是为了看看它是否真的可以工作。

事实上,在写这篇文章的时候,我又有点发烧了:

bash-4.0$ telnet smtp.googlemail.com 25
Trying 74.125.77.16...
Connected to googlemail-smtp.l.google.com.
Escape character is '^]'.
< 220 googlemail-smtp.l.google.com ESMTP Thu, 15 Apr 2010 19:19:39 +0200
> HELO
< 501 Syntactically invalid HELO argument(s)
> HELO client.example.com
< 250 googlemail-smtp.l.google.com Hello client.example.com [666.666.666.666]
> RCPT TO:Me <Me@Example.Com>
< 503 sender not yet given
> SENDER:Me <Me@Example.Com>
< 500 unrecognized command
> RCPT FROM:Me <Me@Example.Com>
< 500 unrecognized command
> FROM:Me <Me@Example.Com>
< 500-unrecognized command
> HELP
< 214-Commands supported:
< 214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP ETRN
> MAIL FROM:Me <Me@Example.Com>
< 250 OK
> RCPT TO:You <You@SomewhereElse.Example.Com>
< 250 Accepted
> DATA
< 354 Enter message, ending with "." on a line by itself
> From: Me <Me@Example.Com>
> To: You <You@SomewhereElse.Example.Com>
> Subject: Testmail
>
> This is a test.
> .
< 250 OK id=1O2Sjq-0000c4-Qv
> QUIT
< 221 googlemail-smtp.l.google.com closing connection
Connection closed by foreign host.

该死,我已经很久没有这样做了。有不少错误: -)

正如大多数人建议的那样,我们不能仅仅通过查看连接上的内容来区分协议是二进制的还是文本的

AFIK

二进制协议-比特是边界 秩序非常重要

Eg RTP

前两位是版本 下一个位是 MarkUp 位

文本协议-特定于协议的分隔符 Order of the fields is not important

Eg,SIP

还有一点是,在二进制协议中,我们可以分割一个字节,也就是说,一个位可能具有特定的个别含义; 而在文本协议中,最小含义单位是 BYTE。你不能分割一个字节。

我们如何在 SOAP 中发送图像文件: 点击这里

这表明二进制数据被附加为[ ATTACHMENT ] ,并且它的引用被保存在 SOAP 消息中。

因此,协议是基于文本的,数据[ Image ]是二进制附件,其编码是不相关的

因此,SOAP 是文本协议,这是由于我们指定 SOAP 头的方式,而不是其中编码的实际数据。

文本协议可以是不言自明的和广泛的。 这是不言而喻的,因为消息本身就包含了字段名。如果不参考协议规范,就无法理解二进制协议消息中的值是什么意思。

它的广泛意味着 HTTP 作为一个文本协议只是制定了简单的规则,但是您可以通过自由添加新的头或通过改变内容类型来传输不同的有效负载来扩展数据结构。报头是元数据,具有协商能力和自适应能力。

如果仅仅看概念不能达到目标,让我举一个实际的例子。 当涉及到数据交换时,结构化数据、非结构化数据和半结构化数据总是被提及。你提到的二进制数据实际上是非结构化数据的,数据不能描述自己,文本数据通常是 JSON 格式的数据,也称为半结构化数据,它可以在一定程度上描述自己,至少知道数据的名称和值。

Web 字段通常使用 JSON 格式来交换数据。GSON 和 FastJson 可以将 JSON 格式的文本转换为 Java 数据对象。 物联网领域通常使用二进制格式。如果采用自定义协议二进制,则可以考虑使用 FastProto(https://github.com/indunet/fastproto)进行解码和编码。