上一篇:各类网络协议(一)html
4、TCP(Transmission Control Protocol,传输控制协议)web
5、HTTP(HyperText Transfer Protocol,超文本传输协议)编程
6、TCP和UDP的区别浏览器
7、相关资料缓存
TCP是一种面向链接(链接导向)的、可靠的基于字节流的传输层通讯协议。TCP将用户数据打包成报文段,它发送后启动一个定时器,另外一端收到的数据进行确认、对失序的数据从新排序、丢弃重复数据。
TCP的特色有:安全
TCP/IP协议族包括运输层、网络层、链路层,而socket所在位置如图,Socket是应用层与TCP/IP协议族通讯的中间软件抽象层。服务器
UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是属于TCP/IP协议族中的一种。如图:cookie
(1) Source Port(源端口号):数据发起者的端口号,16bit。
(2) Destination Port(目的端口号):数据接收者的端口号,16bit。
(3) Sequence Number(顺序号码,Seq):用于在数据通讯中解决网络包乱序(reordering)问题,以保证应用层接收到的数据不会由于网络上的传输问题而乱序(TCP会用这个顺序号码来拼接数据),32bit。
(4) Acknowledgment Number(确认号码,ack):是数据接收方指望收到发送方在下一个报文段的顺序号码(Seq),所以确认号码应当是上次已成功收到顺序号码(Seq)加1,32bit。
(5) Offset(TCP报文头长度):用于存储报文头中有多少个32bit(上图的一行),存储长度为4bit,最大可表示(2^3+2^2+2^1+1)*32bit=60bytes的报文头。最小取值5,5*32bit=20bytes。
(6) Reserved(保留):6bit, 均为0
(7) TCP Flags(TCP标志位)每一个长度均为1bit
CWR:压缩,TCP Flags值0x80。
ECE:拥塞,0x40。
URG:紧急,0x20。当URG=1时,表示报文段中有紧急数据,应尽快传送。
ACK:确认,0x10。当ACK = 1时,表明这是一个确认的TCP包,取值0则不是确认包。
PSH:推送,0x08。当发送端PSH=1时,接收端尽快的交付给应用进程。
RST:复位,0x04。当RST=1时,代表TCP链接中出现严重差错,必须释放链接,再从新创建链接。
SYN:同步,0x02。在创建链接是用来同步序号。SYN=1, ACK=0表示一个链接请求报文段。SYN=1,ACK=1表示赞成创建链接。
FIN:终止,0x01。当FIN=1时,代表此报文段的发送端的数据已经发送完毕,并要求释放传输链接。
(8) 窗口:用来控制对方发送的数据量,通知发放已肯定的发送窗口上限。
(9) 检验和:该字段检验的范围包括头部和数据这两部分。由发端计算和存储,并由收端进行验证。
(10) 紧急指针:紧急指针在URG=1时才有效,它指出本报文段中的紧急数据的字节数。
(11) TCP选项:长度可变,最长可达40字节网络
备注:ISN(Inital Sequence Number):初始化Sequence Number,发生在创建链接时。session
特别注意
Seq:是发送方当前报文的顺序号码。
ack:是发送方指望对方在下次返回报文中给回的Seq。
第一次握手:客户端向服务端发送链接请求包,标志位SYN(同步序号)置为1,顺序号码为X=0。
第二次握手:服务端收到客户端发过来报文,由SYN=1知道客户端要求创建联机,则为此次链接分配资源。并向客户端发送一个SYN和ACK都置为1的TCP报文,设置初始顺序号码Y=0,将确认序号(ack)设置为上一次客户端发送过来的顺序号(Seq)加1,即X+1 = 0+1=1。
第三次握手:客户端收到服务端发来的包后检查确认号码(ack)是否正确,即第一次发送的Seq加1(X+1=1)。以及标志位ACK是否为1。若正确,服务端再次发送确认包,ACK标志位为1,SYN标志位为0。确认号码(ack)=Y+1=0+1=1,发送顺序号码(Seq)为X+1=1。Server收到后确认号码值与ACK=1则链接创建成功,能够传送数据了。
提醒:中断链接端能够是Client端,也能够是Server端。只要将下面两角色互换便可。
第一次挥手:客户端给服务端发送FIN报文,用来关闭客户端到服务端的数据传送。将标志位FIN和ACK置为1,顺序号码为X=1,确认号码为Z=1。意思是说”我Client端没有数据要发给你了,可是若是你还有数据没有发送完成,则没必要急着关闭Socket,能够继续发送数据。因此你先发送ACK过来。”
第二次挥手:服务端收到FIN后,发回一个ACK(标志位ACK=1),确认号码为收到的顺序号码加1,即X=X+1=2。顺序号码为收到的确认号码=Z。意思是说“你的FIN请求我收到了,可是我还没准备好,请继续你等个人消息" 这个时候客户端就进入FIN_WAIT状态,继续等待服务端的FIN报文。
第三次挥手:当服务端肯定数据已发送完成,则向客户端发送FIN报文,关闭与客户端的链接。标志位FIN和ACK置为1,顺序号码为Y=1,确认号码为X=2。意思是告诉Client端“好了,我这边数据发完了,准备好关闭链接了。”
第四次挥手:客户端收到服务器发送的FIN以后,发回ACK确认(标志位ACK=1),确认号码为收到的顺序号码加1,即Y+1=2。顺序号码为收到的确认号码X=2。意思是“我Client端知道能够关闭链接了,可是我仍是不相信网络,怕 Server端不知道要关闭,因此发送ACK后进入TIME_WAIT状态,若是Server端没有收到ACK则能够重传。Client端等待了2MSL后依然没有收到回复,则证实Server端已正常关闭,那好,我Client端也能够关闭链接了。“(在TIME_WAIT状态中,若是TCP client端最后一次发送的ACK丢失了,它将从新发送。TIME_WAIT状态中所须要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待以后链接正式关闭,而且全部的资源(包括端口号)都被释放。)
为何关闭的时候倒是四次挥(握)手?
由于当Server端收到Client端的SYN链接请求报文后,能够直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。可是关闭链接时,当Server端收到FIN报文时,极可能并不会当即关闭SOCKET,因此只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端全部的报文都发送完了,我才能发送FIN报文,所以不能一块儿发送。故须要四步握手。
捕获过滤器中填入表达式:host www.cnblogs.com and port 80(80等效于http)
有多个TCP流时在显示过滤器中填入表达式:tcp.stream eq 0 筛选出第一个TCP流(包含完整的一次TCP链接:三次握手和四次挥手)
每条记录都有以下协议层
(1) Frame: 物理层的数据帧概况
(2)Ethernet II: 数据链路层以太网帧头部信息
(3) Internet Protocol Version 4: 互联网层IP包头部信息
(4)Transmission Control Protocol: 传输层的数据段头部信息,此处是TCP
(5) Hypertext Transfer Protocol: 应用层的信息,此处是HTTP协议
HTTP是一个应用层协议,虽然在2015年已推出HTTP/2版本,并被主要的web浏览器和web服务器支持。但目前使用最普遍的仍是HTTP/1.1版本。有关历史请查阅这里。
它的主要特色可归纳以下:
另外,HTTP请求报文和响应报文都是由开始行(对于请求消息,开始行就是请求行,对于响应消息,开始行就是状态行),消息报头(可选),空行(只有CRLF的行),消息正文(可选)组成。将在下面详细讲解。
报文中的数据都使用ASCII编码,各个字段的长度是不肯定的(除了做为结尾的CRLF外,不容许出现单独的CR或LF字符)。
POST /search HTTP/1.1 Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-silverlight, application/x-shockwave-flash, */* Referer: http://www.google.cn/ Accept-Language: zh-cn Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld) Host: www.google.cn Connection: Keep-Alive Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g; NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y- FxlRugatx63JLv7CWMD6UB_O_r hl=zh-CN&source=hp&q=domety
全部请求方法名称全为大写,目前有9种:
备注
安全性:https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
幂等性:表示的操做至多只会被处理一次,每次调用都将返回第一次调用时的处理结果。
关于HTTP请求GET和POST的区别
(1).提交形式:
GET提交的数据会放在URL以后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的Body中.
(2).传输数据的大小:
HTTP协议自己没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。 而在实际开发中存在的限制主要有:
GET:特定浏览器和服务器对URL长度有限制,例如IE对URL长度的限制是2083字节(2K+35)。对于其余浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操做系统的支持。
所以对于GET提交时,传输数据就会受到URL长度的限制。
POST:因为不是经过URL传值,理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。
(3).安全性:
POST的安全性要比GET的安全性高,具备真正的Security的含义。并且经过GET提交数据,用户名和密码将明文出如今URL上,由于登陆页面有可能被浏览器缓存,其余用户浏览历史纪录就能够拿到帐号和密码了。
报头域指头部中的Key,且不分大小写。
如所见,响应报文结构与请求报文结构惟一真正的区别在于第一行中用状态信息代替了请求信息。状态行(status line)经过提供一个状态码来讲明所请求的资源状况。
HTTP/1.1 200 OK Date: Mon, 23 May 2005 22:38:34 GMT Content-Type: text/html; charset=UTF-8 Content-Encoding: UTF-8 Content-Length: 138 Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux) ETag: "3f80f-1b6-3e1cb03b" Accept-Ranges: bytes Connection: close <html> <head> <title>An Example Page</title> </head> <body> Hello World, this is a very simple HTML document. </body> </html>
状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
1xx:指示信息--表示请求已接收,继续处理。
2xx:成功--表示请求已被成功接收、理解、接受。
3xx:重定向--要完成请求必须进行更进一步的操做。
4xx:客户端错误--请求有语法错误或请求没法实现。
5xx:服务器端错误--服务器未能实现合法的请求。
经常使用状态码:
200 OK:成功返回状态,对应,GET,PUT,PATCH,DELETE。
201 created - 成功建立。
302 Found:重定向,新的URL会在response中的Location中返回,浏览器将会使用新的URL发出新的Request。
例如在IE中输入http://www.google.com. HTTP服务器会返回304, IE取到Response中Location header的新URL, 又从新发送了一 个 Request.
304 Not Modified:表明上次的文档已经被缓存了, 还能够继续使用。
400 bad request - 请求格式错误。
401 unauthorized - 未受权。
403 forbidden - 鉴权成功,可是该用户没有权限。
404 not found - 请求的资源不存在。
405 method not allowed - 该http方法不被容许。
410 gone - 这个url对应的资源如今不可用。
415 unsupported media type - 请求类型错误。
422 unprocessable entity - 校验错误时用。
429 too many request - 请求过多。
500 Internal Server Error:服务器发生了不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常。
报头域指头部中的Key,且不分大小写。
Wireshark、Fiddler、HttpWatch(需结合IE)、Telnet
Wireshark:
在显示过滤器中填入表达式:http and ip.addr == 42.121.252.58 and tcp.port == 80 过滤出http的响应和请求流程
说到HTTP,就不得不提Session和Cookie。但严格来讲,Session和Cookie并非http协议的一部分。因为HTTP协议设计原则是无状态的,可是近年来出现了种种需求,其中cookie的做用就是为了解决HTTP协议无状态的缺陷所做出的努力。后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。 具体来讲cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时咱们也看到,因为采用服务器端保持状态的方案在客户端也须要保存一个标识,因此session机制可能须要借助于cookie机制来达到保存标识的目的,但实际上它还有其余选择。
Session是能够存储针对于某一个用户的浏览器以及经过其当前窗口打开的任何窗口具备针对性的用户信息存储机制。
一般你们认为,只要关闭浏览器,session就消失,其实这是错误的理解。对session来讲也是同样的,除非程序通知服务器删除一个session,不然服务器会一直保留。因为关闭浏览器不会致使session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就能够认为客户端已经中止了活动,才会把session删除以节省存储空间.
(1)第一次访问某个web站点资源时,客户端提交没有带SessionID的请求(请求报文头没有Cookie头域信息)。
而web服务器会检查是否有SessionID过来,没有则建立SessionID,并根据web程序自身定义在请求哪一个资源时添加属于当前会话的信息(也可为空),这个信息列表以SessionID做为标识。而后将SessionID返回给客户端(经过响应报文头的Set-Cookie头域)。
(2 )客户端再次访问同个web站点时,提交带有SessionID的请求(经过Cookie头域存储SessionID)。由服务端判断session是否失效,若是未失效,可查询属于当前会话的信息列表。若是失效,则建立新的session(产生新的SessionID),而原先的session(包含session带的信息列表)则丢失,没法访问。
保存SessionID的方式能够采用Cookie,这样在交互过程当中浏览器能够自动的按照规则把这个SessionID发回给服务器。Cookie的命名方式相似于SessionID。有时Cookie被人为的禁止,因此出现了其余机制以便在Cookie被禁止时仍然可以把SessionID传递回服务器。这种技术叫作URL重写,就是把SessionID直接附加在URL路径的后面,附加方式也有两种,一种是做为URL路径的附加信息,表现形式为http://www.wantsoft.com/index.asp;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 。
另外一种是做为查询字符串附加在URL后面,表现形式为http://www.wantsoft.com/index?js ... 99zWpBng!-145788764 。
一般咱们在说到网络编程时默认是指TCP编程,即用前面提到的socket函数建立一个socket用于TCP通信,函数参数咱们一般填为SOCK_STREAM。即socket(PF_INET, SOCK_STREAM, 0),这表示创建一个socket用于流式网络通信。
SOCK_STREAM这种的特色是面向链接的,即每次收发数据以前必须经过connect创建链接,也是双向的,即任何一方均可以收发数据,协议自己提供了一些保障机制保证它是可靠的、有序的,即每一个包按照发送的顺序到达接收方。
而SOCK_DGRAM这种是User Datagram Protocol协议的网络通信,它是无链接的,不可靠的,由于通信双方发送数据后不知道对方是否已经收到数据,是否正常收到数据。任何一方创建一个socket之后就能够用sendto发送数据,也能够用recvfrom接收数据。根本不关心对方是否存在,是否发送了数据。它的特色是通信速度比较快。你们都知道TCP是要通过三次握手的,而UDP没有。
基于上述不一样,UDP和TCP编程步骤也有些不一样,以下:
TCP:
TCP编程的服务器端通常步骤是:
一、建立一个socket,用函数socket();
二、设置socket属性,用函数setsockopt(); * 可选
三、绑定IP地址、端口等信息到socket上,用函数bind();
四、开启监听,用函数listen();
五、接收客户端上来的链接,用函数accept();
六、收发数据,用函数send()和recv(),或者read()和write();
七、关闭网络链接;
八、关闭监听;
TCP编程的客户端通常步骤是:
一、建立一个socket,用函数socket();
二、设置socket属性,用函数setsockopt();* 可选
三、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
四、设置要链接的对方的IP地址和端口等属性;
五、链接服务器,用函数connect();
六、收发数据,用函数send()和recv(),或者read()和write();
七、关闭网络链接;
UDP:
与之对应的UDP编程步骤要简单许多,分别以下:
UDP编程的服务器端通常步骤是:
一、建立一个socket,用函数socket();
二、设置socket属性,用函数setsockopt();* 可选
三、绑定IP地址、端口等信息到socket上,用函数bind();
四、循环接收数据,用函数recvfrom();
五、关闭网络链接;
UDP编程的客户端通常步骤是:
一、建立一个socket,用函数socket();
二、设置socket属性,用函数setsockopt();* 可选
三、绑定IP地址、端口等信息到socket上,用函数bind();* 可选
四、设置对方的IP地址和端口等属性;
五、发送数据,用函数sendto();
六、关闭网络链接;
TCP和UDP是OSI模型中的运输层中的协议。TCP提供可靠的通讯传输,而UDP则常被用于让广播和细节控制交给应用的通讯传输。
UDP补充:
UDP不提供复杂的控制机制,利用IP提供面向无链接的通讯服务。而且它是将应用程序发来的数据在收到的那一刻,马上按照原样发送到网络上的一种机制。即便是出现网络拥堵的状况下,UDP也没法进行流量控制等避免网络拥塞的行为。此外,传输途中若是出现了丢包,UDO也不负责重发。甚至当出现包的到达顺序乱掉时也没有纠正的功能。若是须要这些细节控制,那么不得不交给由采用UDO的应用程序去处理。换句话说,UDP将部分控制转移到应用程序去处理,本身却只提供做为传输层协议的最基本功能。UDP有点相似于用户说什么听什么的机制,可是须要用户充分考虑好上层协议类型并制做相应的应用程序。
TCP补充:
TCP充分实现了数据传输时各类控制功能,能够进行丢包的重发控制,还能够对次序乱掉的分包进行顺序控制。而这些在UDP中都没有。此外,TCP做为一种面向有链接的协议,只有在确认通讯对端存在时才会发送数据,从而能够控制通讯流量的浪费。TCP经过检验和、序列号、确认应答、重发控制、链接管理以及窗口控制等机制实现可靠性传输。
TCP与UDP区别总结:
一、TCP面向链接(如打电话要先拨号创建链接);UDP是无链接的,即发送数据以前不须要创建链接
二、TCP提供可靠的服务。也就是说,经过TCP链接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保 证可靠交付
三、TCP面向字节流,其实是TCP把数据当作一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,所以网络出现拥塞不会使源主机的发送速率下降(对实时应用颇有用,如IP电话,实时视频会议等)
四、每一条TCP链接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通讯
五、TCP首部开销20字节;UDP的首部开销小,只有8个字节
六、TCP的逻辑通讯信道是全双工的可靠信道,UDP则是不可靠信道