由HTTP深入理解网络通信协议

2017/03/16 HTTP

协议:数据的组织与传输约定

HTTP(HyperText Transfer Protocol)超文本传输协议,是Web通信中最普遍的协议。我们首先应该对“协议”这个词有个直观的了解,协议是什么,是两方或者大众约定俗成的规则,这个规则是静态,通常我们提到HTTP的时候,都会想到网络通信等等,好像是个动态的概念,其实不然,协议就是协议,是个静态的概念,这个协议可以用到网络传输,也可以用到非网络传输,比如,手写的信件,也可以采用HTTP,这只是打个比方来说明协议的概念。

对于HTTP协议,是什么样的呢:其实就是约定通信数据的格式,比如数据想要走HTTP协议传输出去,就一定要按照HTTP进行封装,这样对方才能正确的解析。

  • TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,
  • HTTP是应用层协议,主要解决如何包装数据。

“我们在传输数据时,可以只使用(传输层)TCP/IP协议,但是那样的话,如果没有应用层,便无法识别数据内容。如果想要使传输的数据有意义,则必须使用到应用层协议。  应用层协议有很多,比如HTTP、FTP、TELNET等,也可以自己定义应用层协议。Socket编程接口在设计的时候,就希望也能适应其他的网络协议。所以说,Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,

参考文档

以前的写信告白,:A-B(求婚)A-B(求婚)A-B(求婚) B-A(接收) B-A(接收) B-A(接收) A-B (A知道了)

双通道:

HTTP协议的请求长什么样

GET /  HTTP/1.1
Host: localhost:8080
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Accept: image/webp,image/*,*/*;q=0.8
DNT: 1
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4,zh-TW;q=0.2

注意最后有一个/r/n回车换行符,当然,上面的每一行结尾都是有的,不然打印出来就不会是上面的样式;不同层次的协议对于数据的名称不同

  • 应用层——消息
  • 传输层——数据段(segment)
  • 网络层——分组、数据包(packet)
  • 链路层——帧(frame)
  • 物理层——P-PDU(bit)

看下wireshark的抓包,先看一帧完整的数据,从链路层看

帧数据.png

链路层.png

数据是不断的封装头部,来添加每一个层次的支持,链路层添加了对链路层协议的支持,链路层以太网协议

|目的地址 6个字节|原地址 6个字节|类型 62个字节|数据|CRC校验| |:—–|:—–|:—–|:—–|:—–|

这里的地址,其实是网卡MAC地址,从截图来看,目的MAC地址是 2c:54:cf:ea:21:b3,源MAC地址是80:e6:50:15:f3:a6,而这里的类型,其实是IP协议在链路层的类型,80:00,其实可以看出这里就是封装了一个链路层头部,这就是协议的本质。不信接着看IP层:

IP层.png

在上图的标识中,可以看出,IP层为TCP层添加的数据其实只有个IP层的头部,IP层协议是什么样式呢?区分IP、ARP等

IP层头.png

可以看出,一般IP层头部就是20个字节的数据,其中包含了IP层的版本,首部长度,服务类型等,当然最终要的还有IP源地址跟目的地址,对应帧数据中就是

45:版本号+首部长度,首部长度在当前的协议中,已经没什么用途, 00:服务类型, 01 f8:字节长度,这里包含IP头部+数据的长度 ,对于当前数据长度是504+链路层的14正好是帧数据的长度518 中间的是一些TTL标识之类的字段,最后是目的地址跟源地址,这里是IPv4,所以都是32位的,

c0:a8:af:96 源IP地址,192.168.31.150 c0:a8:1f:36 目的IP地址:192.168.31.54

接着看TCP对于数据的封装,可以猜测,加了个TCP头部:

TCP层.png

TCP头部的样式又是什么样的呢?区分TCP跟UDP等

TCP首部.png

可以看到普通的也就是占用20字节:从具体的请求分析

  • d3 7e :源端口号:Client端一般是经常变动
  • 1f:90:目的端口号: 这里其实是8080
  • 之后就是32位序列号 确认序列号 +其他控制信息
  • 校验和等

最后看下HTTP层的请求信息封装,HTTP是应用层,独立的超文本传输协议,但是对于TCP来说,都是传输数据,看HTTP层的数据

HTTP层.png

在我们请求的时候,会把IP地址算到请求里面,那么为什么HTTP层在wireshark中没相应的表现呢?其实网络地址,是给IP层用的,端口号,是给TCP层用的,真正给HTTP层用的只有上图显示的数据,那就是HTTP协议+请求数据:

HTTP层协议数据.png

TCP/IP已经保证了数据的传输,HTTP层是数据全部是面向业务的的,因此不需要考虑传输相关的问题,所以看到的并没添加额外的头部之类的信息,每行信息都是以/r/n结尾,最后一行还需要额外加个/r/n,标志请求头结束,后面的是请求body,其实这中约束,就算HTTP协议。

简单来说请求报文就是由请求行、请求头、内容实体组成的,每一行的末尾都有回车和换行,在内容实体和请求头之间另有一个空行。其中请求行指定的是请求方法、请求URL、协议版本;请求头是键值对的形式存在的,就是字段名:值;内容实体就是要传输的数据。TCP层不会关心上面的HTTP协议,HTTP层也不会关心底层的数据传输。

wirshark抓的帧数据为什么没有CRC校验?

校验一般是网卡驱动添加的,在发送前,wirshark并没有走那么深, CRC 的校验应该是网卡来做的,如果出现 CRC 校验错误的话,应该丢包了。pcap 能抓到的报文,应该是通过 CRC 校验的。而且抓的报文中已经不包含 CRC 的字节了。wireshark 可以显示 IP 和 TCP/UDP 校验和的正确与否。 参考文档

1,session 在服务器端,cookie 在客户端(浏览器) 2,session 默认被存在在服务器的一个文件里(不是内存) 3,session 的运行依赖 session id,而 session id 是存在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,同时 session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id) 4,session 可以放在 文件、数据库、或内存中都可以。 5,用户验证这种场合一般会用 session 因此,维持一个会话的核心就是客户端的唯一标识,即 session id

作者:冯特罗 链接:https://www.zhihu.com/question/19786827/answer/21643186 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

参考文档

HTTP协议—— 简单认识TCP/IP协议
“/r/n”回车与换行
超文本传输协议
Java Socket 实现HTTP服务器核心
HTTP协议详解(真的很经典)
理解HTTP协议
Javascript 不能在HTTP GET请求的body中包含参数 阅读(1562)

Search

    Table of Contents