二进制协议v。文本协议

时间:2010-04-15 12:06:08

标签: text binary protocols

有没有人对二进制协议有什么好的定义?实际上什么是文本协议?这些在线上发送的比特如何相互比较?

这是维基百科关于二进制协议的说法:

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

哦,来吧!

更清楚一点,如果我有jpg文件将如何通过二进制协议发送,如何通过文本?当然,就线路上发送的比特/字节而言。

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

9 个答案:

答案 0 :(得分:135)

二进制协议与文本协议实际上并不是关于如何编码二进制blob。区别在于协议是围绕数据结构还是围绕文本字符串。让我举个例子: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而不是三个字符'2''0'的int 0' 。这就是基于文本的协议:一种旨在作为(通常是人类可读的)文本行的平面流传递,而不是作为许多不同类型的结构化数据。

答案 1 :(得分:23)

这是一种警察定义:

  

当你看到它时,你会知道的。

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

您在现实生活中遇到的所有协议都将如下所示:

> 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

[我刚刚在现场做了这件事。]

那里的含糊不清楚。

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

  

文本协议是您可以使用telnet

进行调试的协议

也许我在这里显示我的书呆子,但我通过SMTP和POP3实际编写和阅读电子邮件,通过NNTP阅读usenet文章并使用telnet通过HTTP查看网页,除了看其是否真的有用之外别无他法。

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

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.
该死的,自从我做完这件事已经有一段时间了。那里有很多错误: - )

答案 2 :(得分:5)

正如大多数人所说,我们无法通过查看线路上的内容来区分协议是二进制还是文本

AFIK

二进制协议 - 位是边界                   订单非常关键

例如,RTP

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

文本协议 - 特定于协议的分隔符                 字段顺序并不重要

例如,SIP

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

答案 3 :(得分:4)

二进制协议示例:RTPTCPIP

文字协议示例:SMTPHTTPSIP

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

提示:只需跳到示例部分或图表。它们用于说明Tyler's rocking answer

答案 4 :(得分:3)

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

  

o更清楚,如果我有jpg文件将如何通过二进制协议发送以及如何&gt;通过文本?当然,就线路上发送的比特/字节而言。

您应该阅读此Base64

  

任何评论都会被欣赏,我试图在这里找到事物的本质。

我认为缩小字符集的本质是缩小复杂性,实现可移植性和兼容性。很难安排并同意许多人尊重广泛的字符集(或任何广泛的东西)。拉丁文/罗马字母和阿拉伯数字在世界范围内广为人知。 (当然还有其他考虑因素来减少代码,但这是主要的代码)

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

答案 5 :(得分:3)

我无意中发现了这个老问题,并决定加上我的意见,至少要检查一下。

大多数答案解释了文本和二进制协议与机器角度的不同之处。从人的角度来看,文本协议是人类可读/可编辑的(人类可以读取和写入没有解码器/编码器的分组)。这意味着至少有两个好处:简化调试/维护文本协议的实现,以及通过telnet等简单通用工具进行测试的可能性。

另一个小好处:文本协议被视为更可靠,因为(我猜)在协议实现中使用漏洞来执行某些恶意代码是不可能的或者很难,例如:通过利用缓冲区溢出。这是一个很小的好处,因为二进制协议可以通过base64编码实现相同的效果。

文本协议也存在一些缺点:

  • 文本协议实现通常更难以实现 比二进制,因为解析器。
  • 二进制协议占用的带宽较少

尝试编译一些最终建议:

在以下情况下将协议设为文本:

  • 这是一个控制协议,可以作为一系列命令或 请求/回复((交互式)。从实现的角度来看,它可以实现为有限状态机。例如,考虑多媒体流:RTSP - 控制协议,使用状态机并由请求/回复组成 - 是一个文本协议,当RTP是二进制协议时,因为它主要承载自然二进制数据,如多媒体流。
  • 它适用于大量使用:由许多人,实现或应用程序;所以简化的调试/维护非常重要。

答案 6 :(得分:1)

How can we send an image file in SOAP: Click here

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

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

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

答案 7 :(得分:0)

我认为你弄错了。 决定数据在“线路”上的显示方式不是协议,而是决定使用哪种协议传输数据的数据类型。 以tcp socket为例,一个jpeg文件将以二进制协议发送和接收'因为它是二进制数据(不是人类可读的,在32-126 ascii范围之间的字节),但你可以发送/ recv一个文本文件两种协议,你都不会注意到差异。

答案 8 :(得分:0)

文本协议可以是不言自明的和广泛的。 它是不言自明的,因为消息包含消息本身中的字段名称。如果您没有参考协议规范,则无法理解二进制协议消息中哪个值意味着什么。

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