今天想通过抓包实验,巩固一下所学习的网络协议。同时,在知识点上会加上以前遇到的一些问题。这次实验并不是对所有的网络协议都进行分析,而是从下面这个问题出发(面试常被问)。从这一过程中复习学过的网络协议。使用的工具是wireshark。
问题:在浏览器中输入URL后,执行的过程。会用到哪些协议?
例如:查询www.163.com的IP地址过程如下:
(1)域名解析(DNS)
①在浏览器中输入www.163.com域名,首先查看本机的缓存有无该域名记录,如果没有,则向本地DNS服务器请求;
②本地DNS服务器收到请求后,查看是否有该域名的解析,若有,直接返回,完成解析;若没有,则请求根域名服务器;
③根域名服务器收到请求后,根域名返回.com的服务器ip;
④本地域名服务器接到.com服务器地址后,向该域名服务器请求www.163.com,返回163.com域的服务器ip;
⑤本地域名服务器获得163.com域的服务器ip后,发请求到该域名服务器,返回www.163.com域的服务器ip;
⑥本地域名服务器获取该解析后,返回给主机,解析完成,同时自己也将IP地址缓存起来。
(2)发起TCP的3次握手(TCP)
(3)为了将消息从你的PC上传到服务器上,需要用到IP协议、ARP协议。
(4)建立TCP连接后发起HTTP请求。(HTTP)
(5)服务器响应HTTP请求
(6)浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)
(7)断开TCP连接
使用wireshark搜索某一目标地址可以使用以下方法:
DNS报文格式如下:
DNS询问报文如下:
Queries内的格式:
(1)查询名:长度不固定,且不使用填充字节,一般该字段表示的就是需要查询的域名(如果是反向查询,则为IP,反向查询即由IP地址反查域名)。
(2)查询类型:
类型 |
助记符 |
说明 |
1 |
A |
由域名获得IPv4地址 |
2 |
NS |
查询域名服务器 |
5 |
CNAME |
查询规范名称 |
6 |
SOA |
开始授权 |
11 |
WKS |
熟知服务 |
12 |
PTR |
把IP地址转换成域名 |
13 |
HINFO |
主机信息 |
15 |
MX |
邮件交换 |
28 |
AAAA |
由域名获得IPv6地址 |
252 |
AXFR |
传送整个区的请求 |
255 |
ANY |
对所有记录的请求 |
(3)查询类:通常为1,表明是Internet数据(实验数据就为0x0001)。
资源记录(RR)区域(包括回答区域,授权区域和附加区域)格式:
(1)域名(2字节或不定长):它的格式和Queries区域的查询名字字段是一样的。有一点不同就是,当报文中域名重复出现的时候,该字段使用2个字节的偏移指针来表示。比如,在资源记录中,域名通常是查询问题部分的域名的重复,因此用2字节的指针来表示,具体格式是最前面的两个高位是11,用于识别指针。其余的14位从DNS报文的开始处计数(从0开始),指出该报文中的相应字节数。一个典型的例子,C00C(1100000000001100,12正好是头部的长度,其正好指向Queries区域的查询名字字段)。
(2)查询类型:表明资源纪录的类型。
(3)查询类:对于Internet信息,总是IN。
(4)生存时间(TTL):以秒为单位,表示的是资源记录的生命周期,一般用于当地址解析程序取出资源记录后决定保存及使用缓存数据的时间,它同时也可以表明该资源记录的稳定程度,极为稳定的信息会被分配一个很大的值(比如86400,这是一天的秒数)。
(5)资源数据:该字段是一个可变长字段,表示按照查询段的要求返回的相关资源记录的数据。可以是Address(表明查询报文想要的回应是一个IP地址)或者CNAME(表明查询报文想要的回应是一个规范主机名)等。
实验中的查询问题区域:
DNS应答报文:
可以看到Answer RRs和Authority RRs都置为1了。
Answers和Authoritative nameservers详细信息如下:
Ps:DNS占用53号端口,同时使用TCP和UDP协议。DNS在区域传输的时候使用TCP协议,其他时候使用UDP协议。
DNS区域传输的时候使用TCP协议:
原因:辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传送,进行数据同步。区域传送使用TCP而不是UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多。
域名解析时使用UDP协议:
原因:客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。
Connection:Keep-Alive表示采用长连接
请求行由方法字段、URL字段和HTTP协议版本字段。其中,方法字段严格区分大小写,当前HTTP协议中的方法都是大写,方法字段如下介绍如下:
①GET:请求获取Request-URI(URI:通用资源标识符,URL是其子集,URI注重的是标识,而URL强调的是位置,可以将URL看成原始的URI),所标识的资源。
②POST:在Request-URI所标识的资源后附加新的数据;支持HTML表单提交,表单中有用户添入的数据,这些数据会发送到服务器端,由服务器存储至某位置(例如发送处理程序)。
③HEAD:请求Request-URI所标识的资源响应消息报头,HEAD方法可以在响应时不返回消息体。
④PUT:与GET相反,请求服务器存储一个资源,并用Request-URI做为其标识;例如发布系统。
⑤DELETE:请求删除URL指向的资源。
⑥OPTIONS:请求查询服务器的性能,或者查询与资源相关的选项。
⑦TRACE:跟踪请求要经过的防火墙、代理或网关等,主要用于测试或诊断。
⑧CONNECT:保留将来使用。
状态码 |
状态描述 |
简要说明 |
200 |
OK |
客户端请求成功 |
201 |
Created |
请求已经被实现,而且有一个新的资源已经依据请求的需要而创建,且其URI已经随Location头信息返回。 |
301 |
Moved Permanently |
被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一 |
302 |
Found |
在响应报文中使用首部“Location: URL”指定临时资源位置 |
304 |
Not Modified |
条件式请求中使用 |
403 |
Forbidden |
请求被服务器拒绝 |
404 |
Not Found |
服务器无法找到请求的URL |
405 |
Method Not Allowed |
不允许使用此方法请求相应的URL |
500 |
Internal Server Error |
服务器内部错误 |
502 |
Bad Gateway |
代理服务器从上游收到了一条伪响应 |
503 |
Service Unavailable |
服务器此时无法提供服务,但将来可能可用 |
505 |
HTTP Version Not Supported |
服务器不支持,或者拒绝支持在请求中使用的HTTP版本。这暗示着服务器不能或不愿使用与客户端相同的版本。响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体。 |
HTTP长连接和短连接
HTTP协议与TCP/IP协议的关系
HTTP的长连接和短连接本质上是TCP长连接和短连接。HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP有可靠,面向连接的特点。
如何理解HTTP协议是无状态的
HTTP协议是无状态的,指的是协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。也就是说,打开一个服务器上的网页和你之前打开这个服务器上的网页之间没有任何联系。HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)。
什么是长连接、短连接?
在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。
但从HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
TCP短连接
短连接的情况:client向server发起连接请求,server接到请求,然后双方建立连接。client向server发送消息,server回应client,然后一次读写就完成了,这时候双方任何一个都可以发起close操作,不过一般都是client先发起close操作。为什么呢,一般的server不会回复完client后立即关闭连接的,当然不排除有特殊的情况。从上面的描述看,短连接一般只会在client/server间传递一次读写操作
短连接的优点是:管理起来比较简单,存在的连接都是有用的连接,不需要额外的控制手段。
TCP长连接
长连接的情况:client向server发起连接,server接受client连接,双方建立连接。client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。
首先说一下TCP/IP详解上讲到的TCP保活功能,保活功能主要为服务器应用提供,服务器应用希望知道客户主机是否崩溃,从而可以代表客户使用资源。如果客户已经消失,使得服务器上保留一个半开放的连接,而服务器又在等待来自客户端的数据,则服务器将应远等待客户端的数据,保活功能就是试图在服务器端检测到这种半开放的连接。
如果一个给定的连接在两小时内没有任何的动作,则服务器就向客户发一个探测报文段,客户主机必须处于以下4个状态之一:
(1)客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常的,服务器在两小时后将保活定时器复位。
(2)客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务端将不能收到对探测的响应,并在75秒后超时。服务器总共发送10个这样的探测,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。
(3)客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。
(4)客户机正常运行,但是服务器不可达,这种情况与2类似,TCP能发现的就是没有收到探查的响应。
短连接的操作步骤是:
建立连接——数据传输——关闭连接…建立连接——数据传输——关闭连接
长连接的操作步骤是:
建立连接——数据传输…(保持连接)…数据传输——关闭连接
长连接和短连接的优点和缺点
由上可以看出,长连接可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。对于频繁请求资源的客户来说,较适用长连接。不过这里存在一个问题,存活功能的探测周期太长,还有就是它只是探测TCP连接的存活,属于比较斯文的做法,遇到恶意的连接时,保活功能就不够使了。在长连接的应用场景下,client端一般不会主动关闭它们之间的连接,client与server之间的连接如果一直不关闭的话,会存在一个问题,随着客户端连接越来越多,server早晚有扛不住的时候,这时候server端需要采取一些策略,如关闭一些长时间没有读写事件发生的连接,这样可以避免一些恶意连接导致server端服务受损;如果条件再允许就可以以客户端机器为颗粒度,限制每个客户端的最大长连接数,这样可以完全避免某个蛋疼的客户端连累后端服务。
短连接对于服务器来说管理较为简单,存在的连接都是有用的连接,不需要额外的控制手段。但如果客户请求频繁,将在TCP的建立和关闭操作上浪费时间和带宽。长连接和短连接的产生在于client和server采取的关闭策略,具体的应用场景采用具体的策略,没有十全十美的选择,只有合适的选择。
什么时候用长连接、短连接?
长连接多用于操作频繁,点对点的通讯,而且连接数不能太多情况。每个TCP连接都需要三步握手,这需要时间,如果每个操作都是先连接,再操作的话那么处理速度会降低很多,所以每个操作完后都不断开,次处理时直接发送数据包就OK了,不用建立TCP连接。例如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,而且频繁的socket创建也是对资源的浪费。
像Web网站的http服务一般都用短链接,因为长连接对于服务端来说会耗费一定的资源(具体还是要看实际情况以及用户需求)。若Web网站的操作比较频繁,而且有成千上万甚至上亿的客户端,短连接会更节省资源。如果用长连接,同时有成千上万的用户,如果每个用户都占用一个连接的话,资源花费可想而知。所以在并发量大,而且每个用户无需频繁操作的情况下使用短连接会更好。
TCP报文格式:
TCP三次握手:
TCP四次挥手:
TCP报文详细分析(第三次握手):
TCP报文:[29 05 01 bb f4 0a 2c 77 1f a9 79 d2 50 10 01 00 b9 84 00 00]
为了更易理解:[29 05 01 bb]
[f4 0a 2c 77]
[1f a9 79 d2]
[50 10 01 00]
[b9 84 00 00]
源端口:2905(HEX) = 10501(DEC)
目的端口:01bb(HEX) = 443(DEC)
序号:1
确认号:1
十六进制[50 10]转化成二进制[0101 0000 0001 0000]
数据偏移(占4位):单位是4个字节,此字段值为5,所以TCP首部的长度是20字节。
保留(占6位):保留为今后使用,目前置为0。
紧急位URG:0
确认位ACK:1
推送位PSH:0
复位位RST:0
同步位SYN:0
终止位FIN:0
窗口:0100(HEX) = 256(DEC)
检验和:0xb984
紧急指针:0
需要注意的是:四次挥手的序号和确认号。
在TCP要断开连接时,由客户端发送结束报文。[FIN,ACK]报文(第三次挥手)的序号等于最后一次[ACK]报文的确认号加1,而它的确认号等于最后一次[ACK]报文的序号。
UDP报文格式:
UDP报文:[09 06 c3 3b]
[00 57 05 01]
源端口:0906(HEX) = 2310(DEC)
目的端口:c33b(HEX) = 49979(DEC)
长度:57(HEX) = 87(DEC)
校验和:0x0501
IP报文格式:
IP报文:[45 00 00 28]
[1c de 40 00]
[40 06 00 00]
[0a 66 09 5a]
[27 60 84 45]
版本:4
首部长度(单位是4字节):20
区分服务:0x00
总长度(单位是字节):40
标识:0x1cde
十六进制[40 00]转化成二进制[0100 0000 0000 0000]
标志(占3位,即010):Reserved bit: Not set
Do not fragmaent:set
More fragments:Not set
片偏移(占13位):0
生存时间:64
协议:TCP
首部检验和:0x0000
源地址:10.102.9.90
目的地址:39.96.132.69
ARP协议格式:
硬件类型:Ethernet(1)
协议类型:IPv4(0x0800)
硬件地址长度:6
协议地址长度:4
OP:request(1)
发送者MAC地址:Hewlettp_14:c9:c1 (34:64:a9:14:c9:c1)
发送者IP地址:10.102.7.206
目标MAC地址:00:00:00_00:00:00 (00:00:00:00:00:00)
目标IP地址:10.102.127.254
参考:
http://www.cnblogs.com/0201zcr/p/4694945.html
https://jocent.me/2017/06/18/dns-protocol-principle.html#_label0_0