网络基础三之传输层


传输层


1. 端口号
(1)端口号标识了某一主机上唯一的一个网络进程;
(2)端口号用16bit来表示,也就是两个字节,范围是:0 - 65536;
(3)知名端口号范围:0 - 1023;例如:HTTP/FTP/SSH等使用比较广泛的协议,它们的端口号都是固定的;
(4)操作系统动态分配的端口号:1024 - 65535;例如:客户端程序的端口号,就是操作系统从此范围随机分配的;
(5)知名端口号:

服务器名称端口号
SSH22
FTP21
TELNET23
HTTP80
HTTPS443

注意: 一个进程可以有多个端口号;但是一个端口号不能标识多个进程,因为端口号标识了某一台主机上唯一的一个网络进程。
(6)查看端口号的命令:cat /etc/services
(7)通信:在TCP/IP协议中,用源IP,目的IP,源端口号,目的端口号,协议号这样一个五元组来标识一个通信;
(8)常用命令:

名称作用
netstat查看网络状态
pidof通过进程名,查看进程ID
ping查看是否联网
ps查看网络/进程服务

netstat的选项:

选项作用
n拒绝显示别名,能显示数字的全部转换为数字
l仅列出在LISTEN监听下的服务状态
p显示建立相关链接的程序名
t(TCP)仅显示TCP相关的选项
u(UDP)仅显示UDP相关的选项
a(all)显示所有选项,默认不显示LISTEN相关选项

2. UDP协议
2.1 UDP协议格式
在这里插入图片描述

(1)16位UDP长度:整个数据报(UDP首部+UDP数据)的最大长度,也就是说一个UDP能传输的最大长度是64K;
(2)如果校验和出错,报文直接被丢弃;
(3)定长分离报头和有效载荷:前8字节为报头;
(4)根据16位目的端口号向上层进行交付
2.2 UDP协议特点
(1)无连接:UDP协议只要知道对端的IP和端口号就可以进行传输,而不需要建立连接;
(2)不可靠:相比TCP协议(稍后介绍)来说,UDP协议没有重传机制,没有确认机制等,即使因为网络故障该段无法发送到对方主机时,UDP也不会向上层的应用层返回任何错误信息,所以它是不可靠的;
(3)面向数据报:不能够灵活的控制读写数据的次数和数量,应用层交给UDP多长的报文,UDP就会原样发送,既不会拆分也不会合并;
(4)UDP没有真正意义上的发送缓冲区,但是具有接收缓冲区,接收缓冲区不能保证收到的报文和发送过来的报文顺序是一致的,如果接收缓冲区满了,后续到达的报文就会被直接丢弃;
(5)也正是基于上面的这些缺点,UDP不需要在维护连接和可靠性上花费成本,所以它是比较简单并且高效的。
2.3 基于UDP的应用层协议

协议名称作用
NFS网络文件系统
TFTP简单文本传输协议
DHCP动态主机配置协议
BOOTP启动协议(用于无盘设备启动)
DNS域名解析协议
XXX自定义的基于UDP的应用层协议

3. TCP协议
3.1 TCP协议格式
TCP全称:传输控制协议,是面向连接的,协议格式如下:
在这里插入图片描述
(1)4位首部长度:表示该TCP头部有多少个32bit或有过少个4字节,所以TCP协议头部最大长度是(2^4 - 1)*4 = 60;
(2)6位标志位:

标志位名称作用
URG紧急标志位,URG=1时紧急指针有效,设置优先级,打破原有顺序
ACK判断确认序号是否有效,ACK=1时,确认序号有效
PSH提示接收端应用程序立刻将数据从TCP缓冲区中读走
RST复位标志位,对方要求重新建立连接时携带RST标志位
SYN同步报文段,请求建立连接,建立连接之后才能通信
FIN结束报文段,告知对端主机本段要关闭连接

注意: 请求(SYN)和断开(FIN)有且只有一个可以有效,要么都无效。
(3)16位检验和:发送端填充,接收端校验不通过则认为数据有问题,此处的检验不光包含TCP首部,还有TCP数据部分;
(4)16位紧急指针:标识哪部分数据是紧急数据,需要优先处理;
(5)确认序号ack:占(32/8)4字节,期待收到对方下一个报文段的第一个数据字节的序号;序号表示报文段携带数据的第一个字节的编号,确认序号是期待接收到下一个字节的编号,因此当前报文段的最后一个字节+1即为确认序号;
(6)定长分离报头和有效载荷:前20字节为报头;
(7)根据16位目的端口号向上层进行交付
3.2 TCP保证可靠性的机制
从上述的介绍可以看出来,16位检验和与序号的按序到达也是保证TCP可靠性的两个方法,此处着重介绍下面几个机制。
3.2.1 确认应答(ACK)机制

在这里插入图片描述
(1)确认应答机制也叫ACK机制,ACK标志位用来确认报文,每一个ACK都携带了对应的确认序号,意思就是告诉发送方我已经收到了哪些数据,下一次发送数据应该从哪开始发;
(2)从图中可以看出,没有100%可靠的协议,因为最后一个报文总是不会得到响应,一般来说,我们只要确保自己的消息被对方收到即可。
3.2.2 超时重传机制

在这里插入图片描述

主机A给主机B发送数据,由于其他原因数据无法发至主机B,主机A在经过特定时间之后还是没有收到主机B的确认应答,就会进行重发。
在这里插入图片描述

(1)此处主机B有可能收到很多重复的数据,那么可以利用序号去判断哪些数据都是重复的,从而把重复的包都丢弃掉;
(2)这个特定时间应该如何控制呢?
在理想的情况下,只要找到一个最小时间,确保确认应答能够在这个时间内返回即可,但是这个时间随着网络环境和操作系统的不同还是会有很大的差异,如果时间太短,会频繁发送重复的包,如果时间太长,又会影响重传的效率,所以TCP为了保证无论在任何环境下都能比较高性能的通信,它会动态的计算这个最大超时时间。以LINUX为例:时间设置为500ms,每次判定超时时间都是500ms的整数倍;若重发一次得不到应答,则等待2*500ms再次重发;以此类推,以指数形式递增;累计到一定的重传次数,TCP会认为网络或者对端主机出现异常,强制关闭连接。
3.2.3 连接管理机制
在这里插入图片描述

服务器端状态转换:

状态转换说明
CLOSE->LISTEN服务器端调用listen后进入LISTEN状态,等待客户端连接
LISTEN->SYN_RCVD一旦监听到连接请求,将该连接放至内核等待队列,并向客户端发送SYN确认报文
SYN_RCVD->ESTABLISHED服务器收到客户端的确认报文,进入ESTABLISHED状态,表示可以进行数据的读写
ESTABLISHED->CLOSE_WAIT当客户端主动关闭连接,服务器收到结束报文FIN,返回确认报文并进入CLOSE_WAIT状态
CLOSE_WAIT->LAST_ACK进入CLOSE_WAIT状态,服务器准备关闭连接,处理之前的数据;服务器关闭连接时,向客户端发FIN,之后进入LAST_ACK状态,等待最后一个ACK
LAST_ACK->CLOSED服务器收到对FIN的ACK,彻底关闭连接

客户端状态转换:

状态转换说明
CLOSED->SYN_SENT客户端调用connect,发送同步报文段
SYN_SENT->ESTABLISHEDconnect调用成功,进入ESTABLISHED状态,表示可以进行读写数据
ESTABLISHED->FIN_WAIT_1客户端主动调用close关闭连接时,向服务器发送FIN结束报文,同时进入FIN_WAIT_1状态
FIN_WAIT_1->FIN_WAIT_2客户端收到服务器对结束报文的确认,进入FIN_WAIT_2,等待服务器的结束报文段
FIN_WAIT_2->TIME_WAIT客户端收到服务器发来的结束报文段,进入TIME_WAIT状态,并发出LAST_ACK
TIME_WAIT->CLOSED客户端需要等待2MSL,即报文最大生存时间的2倍,才会进入CLOSED状态

这里有几个问题:
(1)三次握手建立连接:

握手次数含义
第一次握手客户端发送SYN(syn=j)到服务器请求建立连接,进入SYN_SENT状态,等待服务器确认
第二次握手服务器收到SYN包,确认客户的SYN(ack=j+1),同时发送自己的SYN(syn=k)包,即发送SYN+ACK至客户端,进入SYN_RCVD状态
第三次握手客户端收到服务器的SYN+ACK包,对其进行确认,发送ACK(ack=k+1),完毕之后客户端和服务器都进入ESTABLISHED状态,连接成功进行读写操作

(2)四次挥手断开连接:

挥手次数含义
第一次挥手客户端请求断开连接,发送FIN=1至服务器,进入FIN_WAIT_1状态
第二次挥手服务器收到客户端的FIN,发出确认报文ACK=1,并发送自己的序号,服务器进入CLOSE_WAIT状态,等待关闭;客户端收到服务器的确认之后进入FIN_WAIT_2状态,等待服务器发送连接释放报文FIN,在此期间需要接收服务器发送的最后数据
第三次挥手服务器发送完最后的数据之后,发送FIN至客户端,进入LAST_WAIT状态,等待客户端确认;客户端收到服务器的FIN,发出确认ACK=1,进入TIME_WAIT状态,此时TCP连接并没有释放
第四次挥手服务器收到客户端的确认,立即进入CLOSED状态,客户端等待2*MSL之后进入CLOSED状态,比服务器迟一些

(3)TIME_WAIT状态:TCP协议规定主动关闭连接的一方要处于TIME_WAIT状态,该状态存在的原因有两个:其一是保证最后一个ACK被对方收到,保证断开的可靠性;其二是保证断开前的数据能够在网上消散开,被双方收到;
(4)CLOSE_WAIT状态 :TCP服务器通知高层的应用进程,客户端向服务器的方向释放了,也就是说客户端主动断开连接,已经没有数据要发送了,但是服务器若是有数据要发送,客户端依然要接受,所以这个状态需要CLOSE_WAIT一段时间。
(5)2*MSL:TCP协议规定等待两个MSL的时间才能回到CLOSED状态,原因有两个:其一是保证在两个传输方向上且尚未被接收或迟到的报文段都已经消失,否则服务器重启之后可能会受到来自上一个进程迟到的数据,而这种数据很有可能是错误的;其二是在理论上保证了报文的可靠到达,因为网络上没有100%可靠的协议,假设最后一个ACK丢失,则服务器会重发一个FIN,此时客户端进程虽然不在了,但是TCP连接仍然还在,仍然可以重发LAST_ACK,重发FIN来回的时间正好是2*MSL;
(6)为什么连接的时候是三次握手,而断开的时候是四次挥手?
答:因为服务器收到客户端发送的SYN连接请求报文时,可以直接发送SYN+ACK进行应答和同步;但是关闭连接时,当服务器收到客户端的FIN断开报文时,并不会立刻关闭SOCKET,所以先回复一个ACK报文,告知客户端“你发的FIN,我已经收到”,只有等服务器的所有报文都发送完毕之后,才会给客户端发送FIN报文,所以需要四次挥手;
(7)为什么不能两次握手,四次握手?
答:(7.1)假设只有两次握手,我们知道在网络中没有100%可靠的协议,若第二个报文丢失,客户端在特定时间内没有收到服务器的确认报文,会以为连接没有建立成功,从而重新发送请求,若有N多个客户端,那么服务器需要花成本去维护这些连接,此时服务器的压力可想而知;再比如,网络延迟或者网络拥塞时,由于客户端没有收到服务器的响应报文,客户端认为这个TCP连接请求丢失,于是进行重发,此时没有阻塞,发送成功,当网络恢复正常时,在最开始阻塞的请求成功的到达了服务器,而服务器会以为是客户端再一次进行数据传输,于是对后来的连接请求进行应答,并为其分配资源,但是客户端会以为该连接丢失,不会去使用这个连接去进行数据传输,这样的话就会浪费服务器的资源,同样使得服务器的压力很大,甚至使得正常的请求都无法得到应答;另一方面,服务器没有收到客户端的响应报文,此时服务器会认为客户端发送数据没有问题,客户端认为服务器收发数据都没有问题,这样显然是不可靠的;(7.2) 因为三次握手显然可以建立好连接并使客户端和服务器“商议”好双方的信息,所以第四次握手就是没有必要的。
3.2.4 流量控制
接收端处理数据的速度是有限的,如果发送方发的太快,就会导致接收端缓冲区满了之后无法接收后续的数据,造成丢包现象,同时就会出现一系列的问题。此时就需要进行流量控制,根据接收方的处理能力,来决定发送方的发送速度。
(1)接收方将自己接收缓冲区剩余空间的大小(可以接收数据的空间大小)放到TCP首部的窗口大小字段,通过ACK标志位告知发送方自己接收缓冲区剩余空间的大小;窗口字段越大,就说明网络吞吐量越高;
(2)接收方一旦发现自己接收缓冲区快满的时候,就会将窗口大小设置成更小的值,并告知发送方,发送方收到该消息之后就会减慢自己的发送速度;
(3)如果接收端缓冲区满了,就会将窗口大小设置为0,此时发送方不再发送数据,但是会定期发送一个窗口探测数据段,用于检测接收端接收缓冲区剩余空间的大小,假设窗口探测数据丢失,那么双方就无法进行通信,所以需要时不时的进行探测。
3.2.5 拥塞控制
(1)拥塞是由于网络问题,会导致的大面积丢包且不能立即重传事件;
(2)慢启动:假设当前网络比较拥堵,而我们在不知道的情况下,贸然发送了大量的数据,就只会雪上加霜,使得情况更加糟糕。此时TCP就引入了慢启动机制,先发送少量的数据,搞清楚当前网络的状态,在做后面的决定;慢启动时启动慢是为了解决网络拥塞,而后期呈指数型增长是为了尽快恢复传输;
(3)拥塞窗口:慢启动有自己的阈值,当拥塞窗口大小没有超过慢启动的阈值时,增长级别是指数级别的,超过这个阈值时,就按照线性方式增长;
(4)当TCP开始启动时,慢启动阈值等于窗口大小;每次超时重发时,慢启动阈值就会变为原来的一半,同时拥塞窗口置为1;
(5)总结:滑动窗口大小 = min(对端主机接收窗口大小,拥塞窗口大小)
在这里插入图片描述
3.3 TCP提高性能的方法
3.3.1 延迟应答
如果接收端主机收到一个ACK就立刻应答,这时返回的窗口大小比较小,网络吞吐量也就比较小,传输效率也就相对比较低。我们可以选择在保证网络不拥塞的情况下尽可能提高传输效率,此时就有了TCP协议的延迟应答机制。当然并不是所有的包都可以延迟应答,在数量和时间上都是由限制的,而且不同的操作系统一般也都是由差异的,如:每隔N个包就需要应答一次,超过最大延迟事件就得应答一次等等。
3.3.2 捎带应答
捎带应答也是为了解决效率问题,很多情况下,客户端和服务器都是一收一发的,但是有时候就可以捎带些其他的信息一起返回。如:三次握手时,服务器受到客户端的SYN之后,直接返回自己的ACK和SYN。
3.3.3 滑动窗口与快重传
滑动窗口用来解决确认应答机制中(对每一个发送的数据报,都要给一个ACK应答,收到ACK后再发送下一个数据)效率比较差的问题。
在这里插入图片描述
正常情况:
(1)窗口大小:无需等待确认应答就可以继续发送数据的最大值,如上图所示窗口大小就是4000个字节(4个段);
(2)发送前4个段时不需要任何ACK确认,可以直接发送;
(3)收到第一个ACK之后,滑动窗口向后移,继续发送第5个段的数据,以此类推(不包括丢包等异常情况,但是滑动窗口允许ACK部分丢失);
(4)操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有得到应答,因为只有确认应答过的数据才能从缓冲区删掉;
(5)滑动窗口越大,网络的吞吐率就越高。

异常情况:
(1)丢失ACK:部分ACK丢了并不要紧,可以通过后续的ACK再次进行确认;
(2)丢包:当某一段报文丢失后,如果发送端主机连续三次收到相同的应答,就会重新发送对应的数据。

在这里插入图片描述

在这里插入图片描述

这种机制也叫快重传,既然快重传效率这么高,为什么还有超时重传呢?原因就在于:当报文只有一个或者两个时,发送方就无法得到连续三次相同的应答,此时就无法使用快重传,只能用超时重传,也就是说:快重传是超时重传的一种“锦上添花”。
3.4 面向字节流
(1)创建一个TCP的SOCKET,同时会在内核中创建一个接收缓冲区和一个发送缓冲区,TCP的一个连接既有发送缓冲区又有接收缓冲区,此时这个连接既可以读数据又可以写数据,所以TCP是全双工的;
(2)由于该缓冲区的存在,TCP的读和写不需要进行匹配;
(3)TCP面向字节流,由应用层决定,即由用户决定。
3.5 沾包问题
(1)这里的“包”指的是应用层的数据包;
(2)避免沾包问题的方法就是明确“包”与“包”之间的边界;
(3)对与定长的包,直接按照固定大小读取即可;对于变长的包,可以在首部约定好包长或者使用明确的分隔符,只要分隔符与正文不冲突即可,可以自定义,如:HTTP协议按行读,每行以’\n’结尾。
3.6 基于TCP的协议

序号协议名称
1HTTP
2HTTPS
3SSH
4TELNET
5FTP
6SMTP
7XXX自定义协议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值