我理解的TCP的三次握手和四次分手

    这学期就开始学网络啦,下下个星期就开课。看看我理解的TCP/IP的三次握手和四次挥手。顺便也总结了一下当用户输入网址的过程中发生了什么。以及关于HTTP的一些基本知识。


    首先我的理解:

    三次握手:

    1. 客户端首先请求说我要请求你的服务器上的资源。
    2. 服务器说好我知道啦。
    3. 这时候客户端收到了服务器的响应又对服务器说我收到啦,谢谢。

    此时建立连接,可以开始传送数据了,这就是三次握手。

    四次挥手:

    可以是服务器先说分手或者是客户端。比如客户端说:

    1. 我这里没有请求了,你可以等把你的东西发完咱们就分手。
    2. 服务收到消息后说,好的,我把手边的东西发完咱们就分手哈。
    3. 等服务器发完手边的东西跟客户端说:我发完了,可以分手了。
    4. 这时候客户端收到说:好哒,收到,咱们分手吧。。。。

    至此为止客户端和服务器端的链接就断开了。


    当然不能像我理解的简单

    三次握手

    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等文件资源。

    1. 当用户输入网页 URL 的时候,WebKit 调用其资源加载器加载该 URL 对应的网页。
    2. 加载器依赖网络模块建立连接,发送请求并接收答复。
    3. WebKit 接收到各种网页或者资源的数据,其中某些资源可能是同步或异步获取的。
    4. 网页被交给 HTML 解释器转变成一系列的词语(Token)。
    5. 解释器根据词语构建节点(Node),形成 DOM 树。
    6. 如果节点是 JavaScript 代码的话,调用 JavaScript 引擎解释并执行。
    7. JavaScript 代码可能会修改 DOM 树的结构
    8. 如果节点需要依赖其他资源,例如图片、CSS、视频等,调用资源加载器来加载它们,但是它们是异步的,不会阻碍当前 DOM 树的创建,直到 JavaScript 的资源加载并被 JavaScript 引擎执行后才继续 DOM 树的创建。

    上面图1,2来自网络,如有侵权,请告之。