协议

更新时间:April 25, 2018

作者:Windson Yang

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处(www.enginego.org)。

什么是协议

计算机使用了多种多样的协议,大家接触得比较多的是HTTP, TCP/IP, FTP, ICMP等,计算机中的协议和我们现实生活中签的协议其实挺像,双方按照协议上的约定发送和解析数据。举个例子,你和你的朋友通过短信约定明天吃饭的时间地点:

明天

中午12点

在公司等

即使改变文字的顺序

明天

在公司等吧,

中午12点

一般人也能理解。不过计算机不一样,你可以把计算机当成患强迫症的朋友,它会要求你发的信息一定要符合一个规则:

日期(两个字)

时间(四个字)

地点(四个字)

那么信息必须按照这个规定发送:

明天(日期)

上午9点(时间)

在公司等(地点)

只要你和朋友都愿意遵守这个约定发送和接受信息,那么你们就互相遵守了协议。

协议的优点

无论对计算机或者人类来说,信息都变得有序和容易处理。当我们知道信息遵守协议A的时候,我们不需要阅读信息都知道前两个字是日期,接着是四个字的时间,最后是四个字的地点。

举个常见的例子,当你使用浏览器访问www.apple.com,浏览器其实是按照HTTP协议的约定向苹果服务器发出信息,协议要求内容:

第一行:请求方法和协议版本(8个字节)
第二行:请求的URL(30个字节)
第三行:缓存策略(30个字节)
...

实际发送的文字内容是:

GET / HTTP/1.1\r\n(请求方法和协议版本)
Host: www.apple.com\r\n(请求的URL)
Connection: keep-alive\r\n(缓存策略)
Pragma: no-cache\r\n
Cache-Control: no-cache\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
DNT: 1\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: en,zh;q=0.9,en-US;q=0.8,zh-CN;q=0.7\r\n

实际发送的二进制信息是:

0000   b0 7f b9 a3 68 36 98 e0 d9 9d a3 8f 08 00 45 00
0010   02 0a 76 f9 40 00 40 06 1e d1 c0 a8 01 58 68 18
0020   79 0b fe 5b 00 50 55 fb ab bc e6 45 57 80 50 18
...

我们可以看到每一行数据都遵守协议的规定传输,在HTTP协议里面这些信息统称为HTTP的请求头部(每行最后的\r\n是换行符,服务器读取到\r\n就知道接下来的内容是下一行)。它们大多有固定的选项,服务器拿到这条信息之后就可以直接对照协议的顺序来返回数据。想了解更多的朋友可以参考An overview of HTTP

协议与API

有时候工程师也会称API为协议,当一组API非常有名,例如HTTP,FTP,大家都知道的情况下,我们可以称它为协议。另外API一般是给另外一方调用的,为了更好理解,假如你开发了一款照片上传的软件,可以让用户上传图片,保存自己与家人的回忆。开发完之后,有很多用户希望加上美颜的功能,你想了下,觉得自己开发这些功能需要花很多时间,看见EngineGo的美图软件有这个功能,那么可以使用它的美颜代码吗?EngineGo这套代码涉及到很多算法以及图形原理,即使把源代码给你,你一时半会也不知道怎么用,而且还考虑到商业秘密的因素,拿到源代码就更难了。这时候,如果EngineGo提供一个外部API(也可以称为接口),使用这个接口和遵守协议类似,首先要了解接口的格式

这个API使用HTTP协议

第一行:图片
第二行:美颜级别
第三行:url是https://www.enginego.org/image/ 

你不需要知道EnginGo如何实现滤镜和美颜的功能,他只需要按照协议把图片以及美颜级别发送到这个URL地址,服务器就会返回一个URL地址,地址包含一张美颜过的图片,你就可以把这张图片展示给用户了。简单来说,API就是接受输入(图片,美颜等级,URL地址)返回结果(美颜后的图片)的模块。