-
从输入URL到页面加载完成期间经历了什么?
作为一个软件开发者,你一定会对网络应用如何工作有一个完整的层次化的认知,同样这里也包括这些应用所用到的技术:像浏览器,HTTP,HTML,网络服务器,需求处理等等。本文将更深入的研究当你输入一个网址的时候,后台到底发生了一件件什么样的事~整个过程大致的的流程是:在浏览器地址栏输入某个网站的URL浏览器通过DNS服务,查询域名的IP地址(浏览器缓存-->操作系统hosts缓存--->路由缓存—>本地域名服务器—>根域名服务器—>顶级域名服务器—>一级域名服务器...,注意图中箭头的含义是上一步查询失败后才会继续下一步,如果上一步直接查询到了,那就直接返回了)发起TCP三次握手,建立连接TCP建立成功后浏览器向服务器发送HTTP请求服务器响应HTTP请求,返回HTML页面断开TCP连接(四次挥手)浏览器解析HTML代码,请求js,css等资源,最后进行页面渲染,呈现给用户1、在浏览器地址栏输入某个网站的URL在一个网络中,不同计算机拥有的ip地址都是唯一的。提供网页的服务器也是一台计算机,所以同样拥有唯一的一个ip。比如百度的某一台服务器ip为111.13.101.208,你完全可以通过111.13.101.208:80去访问百度的首页。但如果你还想访问腾讯、淘宝等其他网站呢?显然以ip方式去访问一个网站是很费劲的。就像我们说天安门在哪的时候不会说天安门在经纬多少多少度一样,而是以人话说在北京哪哪哪。所以,我们同样以别名的方式去记住每一个网站。而这就是DNS服务器干的活。我们在浏览器输入的是一个,人能够轻松记住的域名网址。当我们回车的时候DNS服务器就会去找该域名网址在网络中对应的ip地址,称之为解析域名。2、浏览器通过DNS服务,查询域名的IP地址导航的第一步是通过访问的域名找出其IP地址。DNS查找过程如下:浏览器缓存–浏览器会缓存DNS记录一段时间。有趣的是,操作系统没有告诉浏览器储存DNS记录的时间,这样不同浏览器会储存个自固定的一个时间(2分钟到30分钟不等)。系统缓存–如果在浏览器缓存里没有找到需要的记录,浏览器会做一个系统调用(windows里是gethostbyname),主要去查找了系统中的hosts文件。这样便可获得系统缓存中的记录。路由器缓存–接着,前面的查询请求发向路由器,查看路由器映射表,它一般会有自己的DNS缓存。本地DNS服务器(提供本地连接的服务商)–接下来要检查的就是ISP缓存DNS的服务器。在这一般都能找到相应的缓存记录。递归查询或迭代查询–DNS在解析域名的时候有两种方式:递归查询和迭代查询。本地DNS服务器找不到会将域名发送给其他服务器,进行递归过程或迭代过程,首先会发送到根域名服务器去找,返回顶级域名服务器的IP地址,再请求顶级域名服务器IP返回二级域名服务器IP,再请求二级域名服务器IP返回三级域名服务器IP......直到找到对应的IP地址,返回给浏览器。递归查询是以本地DNS服务器为中心的,是DNS客户端和服务器之间的查询活动,递归查询的过程中“查询的递交者”一直在更替,其结果是直接告诉DNS客户端需要查询的网站目标IP地址;迭代查询则是DNS客户端自己为中心的,是各个服务器和服务器之间的查询活动,迭代查询的过程中“查询的递交者”一直没变化,其结果是间接告诉DNS客户端另一个DNS服务器的地址。DNS递归查询或迭代查询如下图所示:扩展阅读:什么是DNS劫持?什么是301重定向?与301重定向设置教程电脑上不了网将DNS改为114.114.114.114或8.8.8.8可以解决或加快网速的原理是什么?局域网IP和公网IP有何差别?根域名服务器的作用是什么?全球13组根域名服务器中有10组在美国,意味着什么?递归和迭代的区别?3、浏览器发起TCP三次握手,建立TCP连接拿到IP地址后的浏览器很开心,终于可以有目的的去联系远方的“朋友”了,此时作用于传输层的TCP协议向远端服务器发起连接请求,此举称为三次握手:(1)客户端->服务器:你好,我想跟你连接可以吗?(SYN=1,seq=x)(2)服务器->客户端:可以,你确定要连接是吧?(SYN=1,ACK=1,ack=x+1,seq=y)(3)客户端->服务器:确定,我们连接吧!(ACK=1,ack=y+1,seq=x+1)4、TCP建立成功后浏览器向服务器发送HTTP请求OK,连接上了,传输吧,这时就需要将用户输入的地址封装成HTTPRequest请求报文,发送到服务器,服务器收到请求后会发出应答,即响应数据。HTTP请求报文格式:请求行+请求头+空行+消息体,请求行包括请求方式(GET/POST/DELETE/PUT)、请求资源路径(URL)、HTTP版本号;使用Wireshark抓包分析:5、服务器响应HTTP请求,返回HTML页面HTTP响应报文格式:状态行+响应头+空行+消息体,状态行包括HTTP版本号、状态码、状态说明。使用Wireshark抓包分析:6、断开TCP连接(四次挥手)传也传完了,那咱们断开连接吧!(1)客户端->服务器:好了,咱们断开吧(FIN=1,seq=u)(2)服务器->客户端:行,等我稍微检查一下还有没有要发你的数据(ACK=1,ack=u+1,seq=v)(3)服务器->客户端:可以了,咱们断开吧,拜拜(FIN=1,ACK=1,ack=u+1,seq=w)(4)客户端->服务器:好的,再会,拜拜(ACK=1,ack=w+1,seq=u+1)7、浏览器解析HTML代码,请求js,css等资源,最后进行页面渲染,呈现给用户浏览器获取文件后开始利用内核解析了,解析过程中也会出现一些HTTP请求请求一些资源,如js,css等文件,将这些文件下载到本地。浏览器解析HTML文件时会自上而下,起初产生一个DOM树,解析CSS之后产生CSS规树,后将两树进行融合,合成为渲染层,最后调用操作系统的NativeGUI的API绘制。浏览器是多进程的,浏览器能够运行是因为系统给它的进程分配了资源,每打开一个Tab页就相当于创建了一个独立的浏览器进程。浏览器主要包含以下进程:(1)浏览器主进程,负责协调主控,只有一个负责浏览器页面显示,用户交互,如前进后退等负责各个页面的管理、创建和销毁进程网络资源的管理下载等(2)第三方插件进程,每种类型插件对应一个进程,使用时才创建(3)GPU进程,最多一个,用于3D绘制等(4)浏览器渲染进程(浏览器内核),内部是多线程的,主要用于页面渲染、脚本执行、事件处理等重点介绍浏览器内核即渲染进程,页面的渲染、JS的执行、事件的循环都在这个进程内进行。浏览器内核是多线程的,主要包含以下线程:1、GUI渲染线程负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行GUI渲染线程和JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起(相当于被冻结),GUI更新会被保存到一个队列中等JS引擎空闲时立即被执行。2、JS引擎线程(JS内核)负责处理JavaScript脚本程序JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页上只有一个JS线程在运行JS程序JS引擎线程与GUI渲染线程是互斥的,因此如果JS执行时间过长会造成页面渲染不连贯,导致页面渲染加载阻塞。3、事件触发线程用来控制事件循环当JS引擎执行代码块如setTimeOut时(也可能来自浏览器内核的其它线程,如鼠标点击、ajax异步请求等),会将对应任务添加到事件线程中符合条件的事件出发时,该线程会把事件添加到待处理的队列队尾,等待JS引擎处理4、定时触发器线程5、异步http请求线程JS运行机制分析JS分为同步任务和异步任务同步任务都在主线程上执行,形成一个执行栈主线程外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果就在任务队列中放置一个事件执行栈中的所有同步任务执行完毕,系统会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。参考【1】从输入URL到页面加载完成期间经历了什么?(总览篇)【2】浏览器工作原理:从URL输入到页面展现到底发生了什么?
LoveIT 2020-08-29计算机网络 -
面试前你必须知道的HTTP协议知识点(附常见GET、POST面试问题)
1、什么是HTTP协议?HTTP协议是HyperTextTransferProtocol(超文本传输协议)的简称,是用于从万维网(WWW)传输超文本到本地浏览器的传输协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。HTTP是一个应用层协议,由请求和响应组成,是一个标准的客户端服务器架构(C/S)的协议。HTTP还是一个无状态协议。HTTP协议工作于客户端-服务端架构之上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送请求。Web服务器根据接收到的请求后,向客户端发送响应信息。下图所示是HTTP的请求-响应模型示意图。HTTP的请求-响应模型限制了服务器无法在客户端没有请求的时候主动推送消息给客户端。并且HTTP协议是一个无状态协议,即同一个客户端上一次请求和下一次请求之间没有任何关联。HTTP基于TCP通信协议来传递数据(HTML文件,图片文件,查询结果等)。安全版本的HTTPS基于TLS或SSLHTTP默认端口80,HTTPS默认端口443。2、HTTP协议工作过程一次HTTP操作工作过程可分为四步:(1)客户端的浏览器与服务器建立连接。只要单击某个超级链接,HTTP的工作开始。(2)连接建立之后,客户端首先给服务器发送一个请求。请求的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容(3)服务器接收到请求之后给与响应。响应消息的格式为:一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。(4)客户单接收到服务器返回的消息并通过浏览器显示在屏幕上,然后客户机与服务器断开连接。如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,由显示屏输出。对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以了。3、HTTP协议状态响应码一般无论此次请求是否成功响应,服务器都会返回一个状态响应码,HTTP协议中定义了诸多状态码,按照原因可以划分为5大类,如下图所示。常见状态码含义:200(OK):服务器成功处理了请求。204(NOTContent):服务器成功处理了请求,但没有返回任何内容301(MovedPermanently):永久性重定向。表示请求的资源已被分配了新的URI。服务器返回此响应(对GET或HEAD请求的响应)时,会自动将请求者转到新位置302(Found):临时性重定向。表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问。和301MovedPermanently状态码相似,但302Found状态码代表资源不是被永久移动,只是临时性质的。换句话说,已移动的资源对应的URI将来还有可能发生改变。304(NotModified):表示客户端发送附带条件的请求时,服务器端允许请求访问的资源,但未满足条件的情况。400(BadRequest):表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。401(Unauthorized):请求要求身份验证。对于登录后请求的网页,服务器可能返回此响应。403(Forbidden):服务器拒绝请求404(NotFound):表明服务器上无法找到请求的资源。405(MethodNotAllowed):请求的资源不支持请求使用的方法414(Request-URITooLarge):请求参数参数过长500(InternalServerError):服务器内部错误,服务器在处理请求的时候出现错误。501(NotImplemented):服务器不认识或不支持的请求使用的方法502(BadGateway):错误网关503(ServiceUnavailable):服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。504(GatewayTimeout):网关超时,由作为代理或网关的服务器使用,表示不能及时地从远程服务器获得应答。505(HTTPVersionNotSupported):服务器不支持请求中所指明的HTTP版本。4、HTTP协议消息结构(1)客户端请求消息客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(requestline)、请求头(requestheader)、空行(\r\n)和请求数据。使用Wireshark抓包分析:(2)服务器响应消息HTTP响应数据也有4个部分:状态行、消息头部、空行(\r\n)和响应正文。使用Wireshark抓包分析:5、HTTP请求方法HTTP协议中共定义了8种方法或者叫“动作”来表明对Request-URI指定的资源的不同操作方式,具体介绍如下:HTTP/1.0定义了三种请求方法:GET、POST和HEADHTTP/1.1在新增了五种请求方法:DELETE、PUT、OPTIONS、TRACE和CONNECT八种方法具体含义如下:序号方法描述1GET向特定的资源发出请求。请求参数数据都在url中2HEAD类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头3POST向指定资源提交数据进行处理请求(例如提交表单或者上传文件),请求数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。4PUT向指定资源位置上传其最新内容5DELETE请求服务器删除指定的内容。6CONNECTHTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。7OPTIONS返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性8TRACE回显服务器收到的请求,主要用于测试或诊断。注意:1)方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(MothodNotAllowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码501(NotImplemented)。2)HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的HTTP服务器支持扩展自定义的方法。6、GET、POST的区别?打开浏览器,我们输入“GET、POST的区别”查询出来的答案大致如下:(具体参考W3CSchool:HTTP方法:GET对比POST):GET请求的URL长度是有限制的(不同的浏览器和服务器限制不同),但是POST请求没有限制;GET请求比POST请求更安全,因为GET请求的参数就在URL中,当时POST请求的请求参数在请求体中;对参数的数据类型,GET只接受ASCII字符,而POST没有限制;GET请求参数会被完整保留在浏览器历史记录里;相反,POST请求参数不会被浏览器保留;GET请求只能进行url编码(application/x-www-form-urlencoded),而POST支持多种编码方式;GET请求会被浏览器主动缓存,而POST不会,除非手动设置;GET在浏览器回退时是无害的,而POST会再次提交请求。除了上面在W3CSchool这篇文章中提到的区别,在网上还有一种区别也来总结一下:GET产生一个TCP数据包;POST产生两个TCP数据包。具体说就是:对于GET方式的请求,浏览器会把httpheader和data一并发送出去,服务器响应200(返回数据);而对于POST,浏览器先发送header,服务器响应100continue,浏览器再发送data,服务器响应200ok(返回数据)。7、GET请求有ResuqestBody吗?POST请求可以把请求参数写在URL里吗?先给出答案:GET请求有请求体并且可以将请求参数放到请求体中;POST请求也可以将请求参数写到URL上;其实GET和POST在本质上没有区别,都是HTTP协议中的两种发送请求的方法。而HTTP呢,是基于TCP/IP的关于数据如何在万维网中如何通信的协议。HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上requestbody,给POST带上url参数,技术上是完全行的通的。HTTP只是个行为准则,而GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。8、URL中传送参数的长度在Get和Post中的限制这一块其实不是HTTP协议本身的限制,而是不同厂家实现浏览器或服务器的限制,原因很简单:数据量太大对浏览器和服务器都是很大负担。业界不成文的规定是,大多数浏览器通常都会限制url长度在2K~8K字节,而大多数服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,在requestbody偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略。所以,虽然GET可以带requestbody,却不能保证一定能被接收到。9、POST方法比GET方法更安全?从表面上看,GET请求的参数直接在URL中,在地址栏中可以直接看得见,POST的请求参数在请求体中,似乎更安全。从传输角度看,他们都是不安全的,因为HTTP在网络上是明文传输的,只要在网络节点上抓包,就能完整地获取数据报文。因此想要安全传输,就只有加密,也就是HTTPS。现在,当面试官再问你“GET与POST的区别”的时候,你的内心是不是这样的?参考资料[1]听我讲完GET、POST原理,面试官给我倒了杯卡布奇诺[2]GET请求中URL的最大长度限制总结[3]get和post请求有哪些区别?[4]菜鸟教程:HTTP教程
LoveIT 2020-07-18计算机网络 -
深入理解TCP三次握手与四次挥手
一、TCP首部结构详解TCP数据封装在一个IP数据报中,下图是TCP报文数据格式。TCP首部如果不计选项和填充字段,它通常是20个字节。其中比较重要的字段:(0)源端口和目的端口:各自占用2字节,16位,可以表示的最大端口号是2^16=65535,这两个值加上IP首部中的源端IP地址和目的端IP地址唯一确定一个TCP连接。有时一个IP地址和一个端口号也称为socket(插口)(1)序列号seq:占4字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。(2)确认号ack:占4字节,表示期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。(3)标志位,共6个:ACK、SYN、FIN、URG、PSH、RST。重点了解前3个标志ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效SYN:连接建立时用于同步序号。当SYN=1,ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1,ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0。FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放连接URG:当URG=1时,注解此报文应尽快传送,而不要按本来的列队次序来传送。与“紧急指针”字段共同应用,紧急指针指出在本报文段中的紧急数据的最后一个字节的序号,使接管方可以知道紧急数据共有多长;PSH:当PSH=1时,接收方应该尽快将本报文段立即传送给其应用层。RST:当RST=1时,表示出现连接错误,必须释放连接,然后再重建传输连接。复位比特还用来拒绝一个不法的报文段或拒绝打开一个连接;(4)窗口:TCP通过滑动窗口的概念来进行流量控制,可以理解成接收端所能提供的缓冲区大小。TCP利用一个滑动的窗口来告诉发送端对它所发送的数据能提供多大的缓冲区。窗口大小为字节数,起始于确认序号字段指明的值(这个值是接收端正期望接收的字节)。窗口大小是一个16bit字段,因而窗口大小最大为65535字节。(5)校验和:检验和覆盖了整个TCP报文段:TCP首部和数据。这是一个强制性的字段,一定是由发端计算和存储,并由收端进行验证。(6)紧急指针:只有当URG标志置1时紧急指针才有效。紧急指针是一个正的偏移量,和序号字段中的值相加表示紧急数据最后一个字节的序号。二、TCP建立socket通道的过程(TCP三次握手的过程)TCP协议通过三个报文段完成连接的建立,这个过程称为三次握手(three-wayhandshake),过程如下图所示。注:握手之前,主动打开的客户端结束CLOSED状态,被动打开的服务器进入到监听(LISTEN)状态第一次握手:建立连接,客户端向服务器发送一个SYN数据包(syn=x,随机值),之后客户端进入SYN_SEND(同步已发送)状态,等待服务器确认;第二次握手:服务器收到客户端的SYN数据包,读取发现SYN=1,表示客户端要求建立连接,于是服务器向客户端发送SYN+ACK数据包:SYN=1,ACK=1,ack=x+1,seq=y(随机值)表示"确认客户端的序列号有效,服务器能正常接收客户端的消息,并同意创建连接"。之后服务器进入SYN_RECVD(同步收到)状态。第三次握手:客户端收到服务器的SYN+ACK数据包之后,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器就进入到EATABLISHED(连接建立)状态,TCP三次握手成功,之后就可以传输数据了。三次握手动态过程演示:三、TCP连接终止(TCP四次挥手,Four-WayWavehand)建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的,如图:由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN标志来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。客户端发送一个FIN,用来关闭和客户端到服务器的数据传输。此过程发送的报文是:FIN=1,seq=u(等于前面已经传送过来的数据的最后一个字节的序号加1),发送之后客户端进入FIN-WAIT-1(终止等待1)状态。服务器收到连接释放的报文之后,返回确认报文,ACK=1,ack=u+1,并带上自己的序列号seq=v(随机值),此后服务器就进入到CLOSE-WAIT(关闭等待)状态。(此时客户端向服务器的方向就释放了,这时候处于半关闭状态,即客户端已经没有数据要发送了,但是服务器若发送数据,客户端依然要接受。这个状态还要持续一段时间,也就是整个CLOSE-WAIT状态持续的时间。)客户端收到服务器的确认请求后,此时,客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文FIN,不过在这之前服务器发来的细小客户端还是可以正常接收的。终于,服务器发送完数据之后,它向客户端发送一个连接释放报文:FIN=1,ACK=1,ack=u+1,发送完之后服务器处于LAST-WAIT(最后确认)状态。客户端收到服务器的连接释放报文后,发出确认:ACK=1,ack=w+1,而自己的序列号是seq=u+1,此时,客户端就进入了TIME-WAIT(时间等待)状态。注意此时TCP连接还没有释放,必须经过2MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。一般服务器结束TCP连接的时间要比客户端早一些。四、关于TCP三次握手以及四次挥手过程的一些思考1、为什么建立连接是三次握手,但是关闭连接需要四次挥手?因为在建立连接的时候,当客户端向服务器发送SYN数据包,请求建立连接被服务器接收到之后,服务器可以立即发送SYN+ACK报文同意并证明自己可以正常收发数据了(SYN用于同步,ACK用于确认应答,表示同意建立连接)。但是当关闭连接的时候,当客户端向服务器发送FIN报文之后,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,"你发的FIN报文我收到了"。只有等到我服务端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。说的通俗点就是:一方发送FIN只表示自己发完了数据,但是对方有可能还需要发送数据,此时另一方就不能立即回应FIN,而是需要等到把数据发完了再回应FIN。建立连接的过程不存在这些问题,只要可以正常收到数据包并作出正确回应,就可以立即建立连接。2、建立连接为什么需要三次握手?两次或四次不行吗?先说明为什么不能两次?TCP有一个超时重传机制,如果客户端发出SYN包之后,由于网络原因,服务器没能立即响应SYN+ACK包,那么client会再次发起syn包,这一点,已经有过多次实验。如果第二次syn包正常达到且与server端建立了tcp连接,server端维护了一个连接,一次貌似OK,但别忘了,第一次那个syn包可能就在此时达到server端了,于是server端又要维护一个连接,而这个连接是无效的,可以认为是死连接。而一个进程打开的socket是有限度的,维护这些死连接非常耗费资源。所以,二次握手,服务端有较大隐患,容易因为资源耗尽而崩溃。而三次握手既可以解决这个问题,经过三次握手客户端和服务器双方都可以确认对方具有收发数据的能力,从而不会存在无效连接。为什么不采用四次、五次或更多次?这个问题就更简单了,三次握手就可以确认客户端和服务器双方都可以确认对方具有收发数据的能力了,再增加握手,并不能显著提高可靠性,而且也没有必要。3、在关闭阶段,为什么客户端要经历一个2MSL的TIME-WAIT阶段?虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是当网络不可靠的时候,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。具体的工作原理就是:客户端会在发送出ACK之后进入到TIME_WAIT状态。客户端会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么客户端会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(MaximumSegmentLifetime)。MSL指一个报文片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,客户端都没有再次收到FIN,那么客户端推断ACK已经被成功接收,则结束TCP连接。4、如果已经建立了连接,但是客户端突然出现故障了怎么办?TCP设值有一个保活计时器(显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源)。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75s发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。
LoveIT 2020-06-06计算机网络