[toc]
- 第一次握手:Client将SYN置1,随机产生一个初始序列号seq发送给Server,进入SYN_SENT状态;
- 第二次握手:Server收到Client的SYN=1之后,知道客户端请求建立连接,将自己的SYN置1,ACK置1,产生一个acknowledge number=sequence number+1,并随机产生一个自己的初始序列号,发送给客户端;进入SYN_RCVD状态;
- 第三次握手:客户端检查acknowledge number是否为序列号+1,ACK是否为1,检查正确之后将自己的ACK置为1,产生一个acknowledge number=服务器发的序列号+1,发送给服务器;进入ESTABLISHED状态;服务器检查ACK为1和acknowledge number为序列号+1之后,也进入ESTABLISHED状态;完成三次握手,连接建立。
展开
不可以。可能会出现以下情况:已失效的连接请求报文段又传到了服务器端。
client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用 “三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用 “三次握手” 的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。
展开
可以。但是会降低传输的效率。
四次握手是指:第二次握手:Server只发送ACK和acknowledge number;而Server的SYN和初始序列号在第三次握手时发送;原来协议中的第三次握手变为第四次握手。出于优化目的,四次握手中的二、三可以合并。
展开
由于Server没有收到ACK确认,因此会重发之前的SYN+ACK(默认重发五次,之后自动关闭连接),Client收到后会重新传ACK给Server。
如果Client向服务器发送数据,服务器会以RST包响应。
展开
服务器每收到一次客户端的请求后都会重新复位一个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
展开
TCP连接的一方A,随机选择一个32位的序列号(Sequence Number)作为发送数据的初始序列号(Initial Sequence Number,ISN),比如为1000,以该序列号为原点,对要传送的数据进行编号:1001、1002...三次握手时,把这个初始序列号传送给另一方B,以便在传输数据时,B可以确认什么样的数据编号是合法的;同时在进行数据传输时,A还可以确认B收到的每一个字节,如果A收到了B的确认编号(acknowledge number)是2001,就说明编号为1001-2000的数据已经被B成功接受。
- 第一次挥手:Client将FIN置为1,发送一个序列号seq给Server;进入FIN_WAIT_1状态;
- 第二次挥手:Server收到FIN之后,发送一个ACK=1,acknowledge number=收到的序列号+1,同时发送一个自己的序列号;进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
- 第三次挥手:Server将FIN置1,发送一个序列号给Client;进入LAST_ACK状态;
- 第四次挥手:Client收到服务器的FIN后,进入TIME_WAIT状态;接着将ACK置1,发送一个acknowledge number=序列号+1给服务器;服务器收到后,确认acknowledge number后,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。
展开
因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,表示接收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传送。
展开
客户端没有收到ACK确认,会重新发送FIN请求。
展开
第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果Server没有收到ACK,就会重发FIN,如果Client在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。
MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
使用滑动窗口协议实现流量控制。防止发送方发送速率太快,接收方缓存区不够导致溢出。接收方会维护一个接收窗口 receiver window(窗口大小单位是字节),接受窗口的大小是根据自己的资源情况动态调整的,在返回ACK时将接受窗口大小放在TCP报文中的窗口字段告知发送方。发送窗口的大小不能超过接受窗口的大小,只有当发送方发送并收到确认之后,才能将发送窗口右移。
发送窗口的上限为接受窗口和拥塞窗口中的较小值。接受窗口表明了接收方的接收能力,拥塞窗口表明了网络的传送能力。
展开
如果接收方没有能力接收数据,就会将接收窗口设置为0,这时发送方必须暂停发送数据,但是会启动一个持续计时器(persistence timer),到期后发送一个大小为1字节的探测数据包,以查看接收窗口状态。如果接收方能够接收数据,就会在返回的报文中更新接收窗口大小,恢复数据传送。
拥塞控制主要由四个算法组成:慢启动(Slow Start)、拥塞避免(Congestion voidance)、快重传 (Fast Retransmit)、快恢复(Fast Recovery)
- 慢启动:刚开始发送数据时,先把拥塞窗口(congestion window)设置为一个最大报文段MSS的数值,每收到一个新的确认报文之后,就把拥塞窗口加1个MSS。这样每经过一个传输轮次(或者说是每经过一个往返时间RTT),拥塞窗口的大小就会加倍
- 拥塞避免:当拥塞窗口的大小达到慢开始门限(slow start threshold)时,开始执行拥塞避免算法,拥塞窗口大小不再指数增加,而是线性增加,即每经过一个传输轮次只增加1MSS.
无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。(这是不使用快重传的情况)
- 快重传:快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。
- 快恢复:当发送方连续收到三个重复确认时,就把慢开始门限减半,然后执行拥塞避免算法。不执行慢开始算法的原因:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方认为现在网络可能没有出现拥塞。
也有的快重传是把开始时的拥塞窗口cwnd值再增大一点,即等于 ssthresh + 3*MSS 。这样做的理由是:既然发送方收到三个重复的确认,就表明有三个分组已经离开了网络。这三个分组不再消耗网络的资源而是停留在接收方的缓存中。可见现在网络中减少了三个分组。因此可以适当把拥塞窗口扩大些。
- TCP是面向连接的,UDP是无连接的;
什么叫无连接?
UDP发送数据之前不需要建立连接
- TCP是可靠的,UDP不可靠;
什么叫不可靠?
UDP接收方收到报文后,不需要给出任何确认
- TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多;
- TCP是面向字节流的,UDP是面向报文的;
什么意思?
面向字节流是指发送数据时以字节为单位,一个数据包可以拆分成若干组进行发送,而UDP;一个报文只能一次发完。
- TCP有拥塞控制机制,UDP没有。网络出现的拥塞不会使源主机的发送速率降低,这对某些实时应用是很重要的,比如媒体通信,游戏;
- TCP首部开销(20字节)比UDP首部开销(8字节)要大
- UDP 的主机不需要维持复杂的连接状态表
- 数据包校验
- 对失序数据包重新排序
- 丢弃重复数据
- 应答机制:接收方收到数据之后,会发送一个确认(通常延迟几分之一秒);
- 超时重发:发送方发出数据之后,启动一个定时器,超时未收到接收方的确认,则重新发送这个数据;
- 流量控制:确保接收端能够接收发送方的数据而不会缓冲区溢出
- 端口不同:HTTP使用的是80端口,HTTPS使用443端口;
- HTTP(超文本传输协议)信息是明文传输,HTTPS运行在SSL(Secure Socket Layer)之上,添加了加密和认证机制,更加安全;
- HTTPS由于加密解密会带来更大的CPU和内存开销;
- HTTPS通信需要证书,一般需要向证书颁发机构(CA)购买
展开
- 客户端向服务器发送请求,同时发送客户端支持的一套加密规则(包括对称加密、非对称加密、摘要算法);
- 服务器从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥(用于非对称加密),以及证书的颁发机构等信息(证书中的私钥只能用于服务器端进行解密);
- 客户端验证服务器的合法性,包括:证书是否过期,CA 是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配;
- 如果证书受信任,或者用户接收了不受信任的证书,浏览器会生成一个随机密钥(用于对称算法),并用服务器提供的公钥加密(采用非对称算法对密钥加密);使用Hash算法对握手消息进行摘要计算,并对摘要使用之前产生的密钥加密(对称算法);将加密后的随机密钥和摘要一起发送给服务器;
- 服务器使用自己的私钥解密,得到对称加密的密钥,用这个密钥解密出Hash摘要值,并验证握手消息是否一致;如果一致,服务器使用对称加密的密钥加密握手消息发给浏览器;
- 浏览器解密并验证摘要,若一致,则握手结束。之后的数据传送都使用对称加密的密钥进行加密
总结:非对称加密算法用于在握手过程中加密生成的密码;对称加密算法用于对真正传输的数据进行加密;HASH算法用于验证数据的完整性。
展开
- 对称加密:加密和解密采用相同的密钥。如:DES、RC2、RC4
- 非对称加密:需要两个密钥:公钥和私钥。如果用公钥加密,需要用私钥才能解密。如:RSA
- 区别:对称加密速度更快,通常用于大量数据的加密;非对称加密安全性更高(不需要传送私钥)
展开
- 发送者A用私钥进行签名,接收者B用公钥验证签名。因为除A外没有人有私钥,所以B相信签名是来自A。A不可抵赖,B也不能伪造报文。
- 摘要算法:MD5、SHA
- GET是幂等的,即读取同一个资源,总是得到相同的数据,POST不是幂等的;
- GET一般用于从服务器获取资源,而POST有可能改变服务器上的资源;
- 请求形式上:GET请求的数据附在URL之后,在HTTP请求头中;POST请求的数据在请求体中;
- 安全性:GET请求可被缓存、收藏、保留到历史记录,且其请求数据明文出现在URL中。POST的参数不会被保存,安全性相对较高;
- GET只允许ASCII字符,POST对数据类型没有要求,也允许二进制数据;
- GET的长度有限制(操作系统或者浏览器),而POST数据大小无限制
Session是服务器端保持状态的方案,Cookie是客户端保持状态的方案
Cookie保存在客户端本地,客户端请求服务器时会将Cookie一起提交;Session保存在服务端,通过检索Sessionid查看状态。保存Sessionid的方式可以采用Cookie,如果禁用了Cookie,可以使用URL重写机制(把会话ID保存在URL中)。
- 浏览器查询 DNS,获取域名对应的IP地址:具体过程包括浏览器搜索自身的DNS缓存、搜索操作系统的DNS缓存、读取本地的Host文件和向本地DNS服务器进行查询等。对于向本地DNS服务器进行查询,如果要查询的域名包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析(此解析具有权威性);如果要查询的域名不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析(此解析不具有权威性)。如果本地域名服务器并未缓存该网址映射关系,那么将根据其设置发起递归查询或者迭代查询;
- 浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;
- TCP/IP链接建立起来后,浏览器向服务器发送HTTP请求;
- 服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器;
- 浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;
- 浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。