zoukankan      html  css  js  c++  java
  • OSI七层协议与TCP连接

    概述

    为了追求效率,我们写代码,不可能去关注底层知识,但往往到出了问题,或者性能调优。我们就会速手无策,仔细为自己查缺补漏,总结知识点。

    网络协议

    互联网的本质就是一系列的网络协议,让不同计算机能够互相通信。这个协议就叫做OSI协议,根据不同的功能和分工,人为划分七层,当然你也可以划分五层,4层。实际上这些都是不存在的,只是为了让人更好理解这些都是做什么用的。

    物理层:网络通信的数据传输介质,连接不同结点的电缆与设备构成。这些都是专业的说法,其实说白了就是双绞线(网线),光缆这些东西,当然也包括无线电波。传的是比特流,就是0101101。。。这些电信号。

    数据链路层物理地址寻址、数据的成帧、流量控制、数据的检错、重发,负责物理层面的互联,通信传输。接收到比特流,还得人为的分组,让比特流变得有意义的,这就是数据链路层干得活。它以太网协议将电信号分组,一组电信号称之为一个数据包(帧)。然后控制帧在物理信道上传输包括纠错,调节发送速率(防止高速的发送方把低速接收方淹没,需要某种流量控制机制使发送方得知接收方当前还有多少空间)确保数据的可靠性,每一帧都含有报头(head)和数据(data),报头包含发送者(网卡地址),接收者(网卡地址),数据里就是数据包的具体内容。通过数据链路层,我们就可以建立局域网,并让同一局域网络的两台计算机通信,数据链路层就像是一个社区邮差,他认识社区的每户人家,社区中的每个人都可以将信(帧)交给他,让他送给同一社区的另一户人家。

    网络层:数据在节点之间创建逻辑链路,通过路由选择算法,按一定的原则在多个节点的通信子网中选择一条到达目的节点的最佳路径过程,说白就是讲数据传输到目标地址。现在我要找另一社区的老王,我写了一封信,交给邮差,邮差并不认识另一个社区的人,就把信交给邮局处理,邮局根据上面的地址(IP)就能查到对应的地址描述,然后交给另一个社区的邮局。这封信可能要多个邮局的转发,才能到达老王手里。

    传输层负责建立和断开通信连接(数据流动的逻辑通路),记忆数据的分隔等数据传输相关的管理。当发送大量数据时,时间有点长,网络可能会发生中断。怎么保证大量数据的准确性,如果我发送的这个文件数据包可能有一万个包,发送一个,就告诉一次,我收到了,丢了就再发一次,保证我都能准确完整接收到数据包,这就是TCP协议(TCP协议是会绑定IP和端口的协议)。与之对应的还有一个UDP协议,适用于发送少量数据,发出去就拉倒,不管你接没接收,在多人游戏中,一般都是UDP协议,即使丢几个包也只是卡一下,但如果网络不好。。那游戏体验能把电脑砸了。

    会话层:不同机器上的用户之间建立和管理会话(服务器验证登录,断电续传)。我向老王共享了一个文件夹,老王通过我的IP地址要访问我的共享文件夹(建立会话),这时就会要求他输入我的我脑上的账号密码,这是建立会话过程中的身份验证,权限鉴定。老王从我共享的文件夹拷贝数据,这过程就花了几分钟,然后关闭了和我电脑的共享窗口,这时我又传了一个文件上去。老王有过来连接,这时会发现不需要输入密码就能共享到我文件了,这是因为这条会话还没断开(根据应用层设置的时间维护),身份鉴定环节就省略了(保持会话),这时,电脑卡住了,我无奈重启机器(断开会话),老王重新连接我共享文件夹就要去身份鉴定了。

    表示层:处理两个通信系统中交换信息的数据格式变换,数据加密和解密,数据压缩和恢复。我给老王写的一封信,准备早上九点出发去找他,信里的内容是"我上午九点来",可是老王理解成了我九点到他家,虽然信没看错,但因为不同理解,产生了错误的结果。表示层就是专门负责这些有关网络中计算机信息表达方式的问题,除了编码外,还包括数组,浮点数,声音等多种数据结构,以达到在网络中传输的信息双方的解释都是一样的,在计算机内部表示法和网络的标准表示法之间进行转换。

    应用层为应用程序提供服务并规定应用程序中通信相关的细节

    TCP协议三次握手建立连接

    两台计算机如何交流,就好比我们两个人,使用同一种语言自然而然的就能表达我们的想法,因此计算机他们也需要定义共通的东西进行交流,TCP/IP为此而生,它不是一个协议而是一个协议家族的统称,它们的成员包括TCP协议,HTTP协议,IP协议等等,本章讲的是TCP协议建立连接和断开连接的过程,客户端程序想要访问服务器某个应用程序就必须发送一个通信请求,经过三次握手建立连接四次挥手终止连接,下面看看具体过程。

    位码就是TCP标志位,有6种标示==>建立联机(SYN),确认(ACK),传送(PSH),结束(FIN),重置(RST),USG(紧急)

    状态===>CLOSED(初始化状态),SYN_SENT(等待状态),ESTABLISHED(连接建立状态),LISTEN(监听状态),SYN_RCVD(表示接收到SYN报文),

    三次握手

    1. 第一次握手:客户端发送位码SYN = 1,seq = 0的数据包到服务器,并进入SYN_SENT状态等待确认,服务器由SYN = 1知道,有客户端要建立联机了。
    2. 第二次握手:服务器收到要确认联机的信息,向客户端发送SYN = 1,ACK = 1,ack number = 1(客户端的seq + 1),seq = 0的数据包,服务器进入接收到报文状态。
    3. 第三次握手:客户端接收到服务器发送的数据包,检查ack number是否是第一次发送的seq + 1,位码ACK是否为1,验证正确。再次向服务器发送一个ack number = 1(服务器发送过来的seq + 1),ack = 1,seq = 1的数据包。服务器收到后确认ack = 1,ack number= 1(服务器seq+1),建立连接成功。

    抓包工具查看握手过程

    第二次握手

     第三次握手

     TCP四次挥手断开连接

    可以发现,三次握手是客户端先发起的,而四次挥手客户端和服务器都可以率先发起挥手的动作。客户端和服务器总共发送4个包确认连接断开,也形象称为四次挥手。

    状态=====>FIN_WAIT1(主动关闭连接,发送FIN报文,进入终止等待1),FIN_WAIT2(终止等待2),TIME_WAIT(等待状态),CLOSE_WAIT(等待关闭状态),LAST_ACK(最后等待状态)

    四次挥手

    1. 第一次挥手:数据传输完成后,客户端A发出连接释放报文并停止发送数据,报文的报头中FIN=1,ACK = 1,seq number =73396,ack number = 13704(已经传输完成最后一个字节的序号+1),数据包发送给服务器端,并进入FIN_WAIT1状态。
    2. 第二次挥手:服务器收到这个连接释放报文,发出确认报文,ACK = 1,ack number = 73397,seq number =13704(序列号)给客户端,进入半关闭状态,并且通知高层应用进程,客户端向服务器的方向就释放了。这时,客户端已经没有数据发送了,但服务器如果向客户端发送数据,客户端依然接受,这个阶段就是CLOSE_WAIT状态的持续时间。
    3. 第三次挥手:客户端收到服务器的确认报文后,进入了终止等待2状态,继续等待服务器发送连接释放的报文。服务器把最后的数据发送完毕后,向客户端发送连接释放的报文,FIN = 1,ACK = 1,ack number = 73397,seq number=13704(序列号)发送完后,服务器进入最后确认的状态,等待客户端确认。
    4. 第四次挥手:客户端收到服务器连接释放报文后,必须向服务器发出确认报文,ACK = 1,ack number = 13705,seq number = 73397,然后客户端进入时间等待状态,此时的TCP连接未释放,必须经过2MSL(最长报文寿命)的时间后,客户端撤销相应TCB(传输控制块)后,进入CLOUSED状态,这是因为如果网络不可靠,确认报文可能发丢了,服务器端会不断FIN给客户端,再这2MSL时间内可以重新发一次确认报文,然后再次等待2MSL,如果这时间内没在收到FIN报文,就推断确认报文已经被服务器接收。服务器则只是收到客户端发出的确认,立即进入CLOUSED状态。

    抓包工具查看挥手过程

     

    第二次挥手

    第三次挥手

    第四次挥手

    握手要三次?挥手要四次?

    TCP协议的双方是双工的,也就是说通信双方都可以向对方发送消息,也都可以独立关闭自己自己一方的通信通道。在这顺便说下半双工,说白了就是不同时,A可以给B发消息,B也可以给A发消息,但A给B发的时候,B不能给A发。三次握手确认两件事,知道双方都准备好了,初始序列号进行确认协商。如果只有两次,可能会造成死锁。客户端给服务器发送请求连接,服务器收到这个请求,并发送确认报文。发送完后,服务器按两次握手的协定,认为连接已经建立,开始发送数据。但这时因为某种原因,服务器的确认报文传丢了,客户端懵逼了,不知道服务器是否收到自己的请求,建立什么序列号。客户端就认为连接还未建立,忽略服务器传来的任何数据,傻傻的等待服务器的确认报文,服务器发出的数据超时后,就重复发出同样数据,死锁就产生了。如果是四次握手哪?四次握手是可行的,但是这样一来会造成资源的浪费,因为三次握手已经确认好所有的事情了,没必要在浪费一次资源。

    服务器收到客户端的请求连接报文,立即就可以给应答建立联机了。但关闭连接时,服务器收到这个关闭连接的报文,并不能立即停止,因为还有数据未发送完毕,只能回一个“我知道啦”的应答报文。只有数据全部发送完毕后,服务器才发送说FIN,“我数据传完了”的报文等待确认,然后终止连接。所有需要四次挥手。

    ===============================================================

    如发现错误,请及时留言,lz及时修改,避免误导后来者。感谢!!!

  • 相关阅读:
    STL之vector
    [洛谷P3942] 将军令
    [洛谷P2127] 序列排序
    [USACO07FEB]新牛棚Building A New Barn
    [洛谷P1120] 小木棍 [数据加强版]
    [洛谷P1438] 无聊的数列
    我的Emacs配置
    [CQOI2015]任务查询系统
    可持久化数组入门
    学习openstack(六)
  • 原文地址:https://www.cnblogs.com/dslx/p/10686444.html
Copyright © 2011-2022 走看看