Linux网络
Posted lhxw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux网络相关的知识,希望对你有一定的参考价值。
网络是Linux系统最核心的功能,网络把计算机或局域网连接到一起,本质上是一种进程间通讯的方式,特别是跨系统的进程间通讯,必须通过网络。
网络模型
网络中常提起的有七层负载均衡,四层负载均衡,三层设备,二层设备。
这些层来自于国际标准组织定制的 开放式系统互联通讯参考模型(Open systen Interconnection Reference Model), 简称 OSI 网络模型。
OSI 模型把网络互联的框架分为:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
应用层:负责为应用程序提供统一的接口。
表示层:负责把数据转换成兼容接受系统的格式。
会话层:负责维护计算机之间的通信连接。
传输层:负责为数据加上传输表头,形成数据包。
网络层:负责数据的路由和转发。
数据链路层:负责MAC寻址、错误侦测和改错。
物理层:负责在物理网络中传输数据帧。
OSI 模型有些复杂,也没提供一个可实现的方法,所以在Linux中,我们实际上使用的是四层模型,TCP/IP网络模型。
TCP/IP模型,把网络互联的框架分为 应用层、传输层、网络层、网络接口层。
应用层:负责性用户提供一组应用程序,如 HTTP、FTP、DNS等。
传输层:负责端到端的通信,如TCP、UDP等。
网络层:负责网络包的封装,寻址和路由,如IP、ICMP等。
网络接口层:负责网络包在物理网络中的传输,如MAC寻址、错误侦测、通过网卡传输网络帧等。
Linux实际按照TCP/IP模型,实现网络协议栈,平时交流习惯上海市用OSI七层模型描述,七层和四层负载均衡,对应的分别是OSI模型中的应用层和传输层(对应到TCP/IP模型中,实际上是四层和三层)。
Linux网络栈
有了TCP/IP模型后,在网络传输时,数据包就会按照协议栈,对上一层发来的数据进行逐层处理;然后封装上改层的协议头,再发送给下一层。
网络包在每一层的处理逻辑,都取决于各层采用的网络协议,如在应用层,一个提供REST API的应用,
可以使用HTTP协议,把需要传输的JSON数据封装到HTTP协议中,然后向下传递给TCP层。
封装就是在原来的负载前后,增加固定格式的元数据,原始的负载数据并不会被修改。
如:通过TCP协议通信的网络包为例 ,如图,应用程序在每一层的封装格式:
其中:
-
传输层在应用程序数据前面增加了TCP头;
-
网络层在TCP数据包钱增加了IP头;
-
网络接口层在IP数据包前后分别增加了帧头和帧尾。
新增的头部和尾部,按照特定的协议格式填充:
TCP协议:
TCP是一种面向连接(连接导向)的、可靠的基于字节流的传输层通信协议。TCP将用户数据打包成报文段,它发送后启动一个定时器,另一端收到的数据进行确认、对失序的数据重新排序、丢弃重复数据。
TCP的特点有:
- TCP是面向连接的运输层协议
- 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点的
- TCP提供可靠交付的服务
- TCP提供全双工通信。数据在两个方向上独立的进行传输。因此,连接的每一端必须保持每个方向上的传输数据序号。
- 面向字节流。面向字节流的含义:虽然应用程序和TCP交互是一次一个数据块,但TCP把应用程序交下来的数据仅仅是一连串的无结构的字节流。
TCP协议三次握手四次挥手:
特别注意
Seq:是发送方当前报文的顺序号码。
ack:是发送方期望对方在下次返回报文中给回的Seq。
建立连接需要三次握手
第一次握手:客户端向服务端发送连接请求包,标志位SYN(同步序号)置为1,顺序号码为X=0。
第二次握手:服务端收到客户端发过来报文,由SYN=1知道客户端要求建立联机,则为这次连接分配资源。并向客户端发送一个SYN和ACK都置为1的TCP报文,设置初始顺序号码Y=0,将确认序号(ack)设置为上一次客户端发送过来的顺序号(Seq)加1,即X+1 = 0+1=1。
第三次握手:客户端收到服务端发来的包后检查确认号码(ack)是否正确,即第一次发送的Seq加1(X+1=1)。以及标志位ACK是否为1。若正确,服务端再次发送确认包,ACK标志位为1,SYN标志位为0。确认号码(ack)=Y+1=0+1=1,发送顺序号码(Seq)为X+1=1。Server收到后确认号码值与ACK=1则连接建立成功,可以传送数据了。
断开连接需要四次挥手
提醒:中断连接端可以是Client端,也可以是Server端。只要将下面两角色互换即可。
第一次挥手:客户端给服务端发送FIN报文,用来关闭客户端到服务端的数据传送。将标志位FIN和ACK置为1,顺序号码为X=1,确认号码为Z=1。意思是说”我Client端没有数据要发给你了,但是如果你还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以你先发送ACK过来。”
第二次挥手:服务端收到FIN后,发回一个ACK(标志位ACK=1),确认号码为收到的顺序号码加1,即X=X+1=2。顺序号码为收到的确认号码=Z。意思是说“你的FIN请求我收到了,但是我还没准备好,请继续你等我的消息" 这个时候客户端就进入FIN_WAIT状态,继续等待服务端的FIN报文。
第三次挥手:当服务端确定数据已发送完成,则向客户端发送FIN报文,关闭与客户端的连接。标志位FIN和ACK置为1,顺序号码为Y=1,确认号码为X=2。意思是告诉Client端“好了,我这边数据发完了,准备好关闭连接了。”
第四次挥手:客户端收到服务器发送的FIN之后,发回ACK确认(标志位ACK=1),确认号码为收到的顺序号码加1,即Y+1=2。顺序号码为收到的确认号码X=2。意思是“我Client端知道可以关闭连接了,但是我还是不相信网络,怕 Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。“(在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。)
为什么关闭的时候却是四次挥(握)手?
因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
以上是关于Linux网络的主要内容,如果未能解决你的问题,请参考以下文章