HTTP协议底层通信揭秘 当然, 机器间若想通过稀薄的空气传输数据, HTTP是做不到的。HTTP协议执行操作, 得借助一些更简单的抽象才行。实际上, 现代操作系统具备这样一个功能, 那就是可让不同程序在IP网络间, 靠TCP协议来有纯文本的网络会话。而HTTP协议恰好利用了此功能。也就是说, HTTP协议精确地描述了两台主机间借助TCP传输时的信息格式, 凭借这个来提供HTTP的各项功能。要是持续进一步去观察HTTP的底层达成细节, 那你会抵达借助能够便利操作的网络协议栈里面靠最下方的一级。认真去阅读代码清单1 - 4所展示的.py, 它朝着谷歌地图起始了跟前面三个程序同样的网络请求。存在不同之处的是, .py朝着网络递送了一份无加工处理的文本信息当作请求, 并且接收到了好多无加工处理的文本当作响应。代码表单1 - 4, 直接运用套接字跟谷歌地图进行通信, #!/usr/bin/env # 属于 , 第三 # .解析 取值为\GET /maps/api//json?{}false HTTP/1.1\r\n\主机: :80\r\n\用户代理:.py ( 属于 )\r\n\: 关闭\r\n\\r\n\定义 ():套接字 .()套接字对(, 80)进行操作 .()套接字对.(.(ascii))赋值为空字节串当 为真时:更多内容 套接字接收(4096)如果 没有更多内容: (.(utf - 8))如果 是空字符串:(207 N. 街道, , 俄亥俄州)从.py到.py, 存在一个本质上的差异。原先的3个程序, 每个都运用了一个库。这些库的实现已然被提供了。我们能够借助这些库去解析繁杂的网络协议。在这个例子里, 我们深入到了最底层: 运用主机操作系统给出的原始()函数来支撑IP网络上的网络通信。也就是说, 这种编写网络程序的方式跟使用C语言的底层系统程序员所采用的一致。在后续的几章中, 读者会学到更多关于套接字的知识。当前从.py中能观察到, 原始网络通信的过程是发送以及接收字节串的过程。被发送出去的查询属于一个字节串, 而被接收到的响应同样是一个字节串。在这个例子当中, 我们把这个规模较大的响应字节串打印至屏幕。如此一来, 读者便能够直观地感受到底层操作所具备的魅力了。在1.6节里解释了为什么要在打印之前对字符串进行解码我们能够凭借()函数所传入的参数知晓该HTTP查询的具体详情。由此能够看到, 查询当中涵盖了关键字GET此代表期望进行的操作的名字, GET之后紧跟着待获取文档的路径以及所支持的HTTP版本。进行GET /maps/api//json?207N.St%2C%2COHfalse HTTP/1.1操作, 其中GET信息之后跟着一些请求头, 这些请求头每一个都包含了名称、冒号以及值。最后是表示请求结束的回车符和换行符。运行.py, 查询的响应将会被直接打印出来, 如同代码清单1-5所展示的那样。在这个例子当中, 我仅仅是将响应于屏幕上进行打印, 而并未编写复杂的文本处理代码用以解析这一响应。之所以这么做, 是由于, 我觉得阅读在屏幕上打印出来的HTTP响应, 能够助力读者更优地知晓HTTP响应的形式。与之相较, 去理解用于解析HTTP响应所运用到的代码, 那就困难得多了。代码清单1 - 5 .py运行之后输出的是HTTP/1.1 200 -, 其类型为/json, 编码格式是UTF - 8, 日期是2013年11月23日星期六18点34分30秒, 还有2013年11月24日星期日18点34分30秒, 中间有逗号, 最大存活时间等内容, 允许的方法是*, 预防跨站脚本攻击设置为1, 模式为阻止框架, 连接状态为关闭, 端口是80, 数据内容为{。东西南北中, 方位表述真不同, 207号在北边, 那是位于美国俄亥俄州的一处地方, 编号为43502,其具体位置所蕴含的经纬度, 纬度是41., 经度则是 -84., 各种类型也都有。::\, OK}能够瞧见, HTTP响应的结构跟HTTP请求颇为近似。先是状态行, 紧接着是一些响应头。响应头后面存在一个空行, 随后便是响应体。响应体是一种数据结构, 亦即是JSON这种简易的格式。这个JSON是先前查询的回复结果, 对查询谷歌地理编码API返回的地理位置予以描述。当然咯, 此处的所有状态以及响应头实际上都是先前程序里运用库处理的底层详情。在这个例子当中, 能够看到, 要是不存在分层这种情况, 那么关于网络通信那种具体的细节究竟会是怎样的一种状况。