这学期就开始学网络啦,下下个星期就开课。看看我理解的TCP/IP的三次握手和四次挥手。顺便也总结了一下当用户输入网址的过程中发生了什么。以及关于HTTP的一些基本知识。
首先我的理解:
三次握手:
- 客户端首先请求说我要请求你的服务器上的资源。
- 服务器说好我知道啦。
- 这时候客户端收到了服务器的响应又对服务器说我收到啦,谢谢。
此时建立连接,可以开始传送数据了,这就是三次握手。
四次挥手:
可以是服务器先说分手或者是客户端。比如客户端说:
- 我这里没有请求了,你可以等把你的东西发完咱们就分手。
- 服务收到消息后说,好的,我把手边的东西发完咱们就分手哈。
- 等服务器发完手边的东西跟客户端说:我发完了,可以分手了。
- 这时候客户端收到说:好哒,收到,咱们分手吧。。。。
至此为止客户端和服务器端的链接就断开了。
当然不能像我理解的简单
三次握手
OSI参考模型中的网络层,在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接。
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的syn(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据,在上述过程中,还有一些重要的概念:
未连接队列:在三次握手协议中,服务器维护一个未连接队列,该队列为每个客户端的SYN包(syn=j)开设一个条目,该条目表明服务器已收到SYN包,并向客户发出确认,正在等待客户的确认包。这些条目所标识的连接在服务器处于Syn_RECV状态,当服务器收到客户的确认包时,删除该条目,服务器进入ESTABLISHED状态。
SYN-ACK 重传次数:服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进行首次重传,等待一段时间仍未收到客户确认包,进行第二次重传,如果重传次数超 过系统规定的最大重传次数,系统将该连接信息从半连接队列中删除。注意,每次重传等待的时间不一定相同。
半连接存活时间:是指半连接队列的条目存活的最长时间,也即服务从收到SYN包到确认这个报文无效的最长时间,该时间值是所有重传请求包的最长等待时间总和。有时我们也称半连接存活时间为Timeout时间、SYN_RECV存活时间。
四次挥手
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是 当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送。
服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
服务器B关闭与客户端A的连接,发送一个FIN给客户端A。
客户端A发回ACK报文确认,并将确认序号设置为收到序号加1。
TCP采用四次挥手关闭连接如图所示为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的建 连请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅 表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之 后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
意思就是:客户端告诉服务器我没有数据发送给你了,但不代表此时服务器此时已经把所有的数据都发送给客户端了,所以需要等到服务器发送完所有的数据,主动发送报文告诉客户端,我这里的数据也发送完了。这个时候客户端知道了服务器端数据发送完了。两边都清楚,就可以断开连接。
为什么要进行TCP连接
首先看下http的网络层次:
在Internet中所有的传输都是通过TCP/IP进行的。HTTP协议作为TCP/IP模型中应用层的协议也不例外。
HTTP是基于传输层的TCP协议,而TCP是一个端到端的面向连接的协议。所谓的端到端可以理解为进程到进程之间的通信。所以HTTP在开始传输之前,首先需要建立TCP连接,而TCP连接的过程也就需要上面所谓的“三次握手”。
在TCP三次握手之后,建立了TCP连接,此时HTTP就可以进行传输了。一个重要的概念是面向连接,既HTTP在传输完成之间并不断开TCP连接。比如一个页面一共需要20个http请求:这上面20个HTTP请求,只依靠一个TCP连接就够了,这就是所谓的持久连接。也是所谓的一次HTTP请求完成。一直到没有http请求,四次挥手断开连接。
建立一次http请求的过程
我的想法是:当用户接受用户输入后,首先教给DNS解析对应的IP,并发送给相应的服务器。然后客户端向服务器发送请求改网址网页,服务器收到后,向客户端返回网页信息。浏览器得到后把得到的网页从字节编程一个个的Token,然后渲染成DOM tree。浏览器渲染页面,并异步加载网页中通过异步的方式加载的
javascript,css等文件资源。
- 当用户输入网页 URL 的时候,WebKit 调用其资源加载器加载该 URL 对应的网页。
- 加载器依赖网络模块建立连接,发送请求并接收答复。
- WebKit 接收到各种网页或者资源的数据,其中某些资源可能是同步或异步获取的。
- 网页被交给 HTML 解释器转变成一系列的词语(Token)。
- 解释器根据词语构建节点(Node),形成 DOM 树。
- 如果节点是 JavaScript 代码的话,调用 JavaScript 引擎解释并执行。
- JavaScript 代码可能会修改 DOM 树的结构
- 如果节点需要依赖其他资源,例如图片、CSS、视频等,调用资源加载器来加载它们,但是它们是异步的,不会阻碍当前 DOM 树的创建,直到 JavaScript 的资源加载并被 JavaScript 引擎执行后才继续 DOM 树的创建。
上面图1,2来自网络,如有侵权,请告之。