TCP协议和UDP协议-8.28


HTTP协议和HTTPs协议属于应用层,按照TCP/IP模型,讲解传输层,传输层分为TCP协议和UDP协议。
请添加图片描述

端口号的扩展
端口号(Port)标识了一个主机上进行通信的不同的应用程序(进程)。利用ip地址+端口号可以定位全球上唯一一个进程。
请添加图片描述
ip决定的是服务器主机位置,端口号决定的是哪一个应用处理程序。
可以使用netstat -nltp命令查看协议号、源ip端口和目标ip端口;通过这五个数字可以识别一个通信。
端口号范围划分:

0-1023:知名端口号,服务于HTTP、FTP这些广为人知的应用层协议,

ssh服务器使用22端口、ftp使用21、telnet使用23、http使用80、https使用443等。

1024-65535:操作系统动态分配的端口号。
可以查看所有的执行端口号:cat /etc/services
netstat:查看网络状态的工具,常用选项

l :进查看监听状态
t:进查看tpc相关
u:查看udp相关
a:显示所有
n:拒绝显示别名,都转为数字

pidof:查看服务器的进程id

pidof 进程名
结合xargs使用:pidof 进程名 | xargs kill -9 //杀死该进程。

https://blog.csdn.net/weixin_47257473/article/details/132760509

udp协议端格式

任何协议都要优先解决两个问题:

a.如何实现分离(封装)
b.如何交付
UDP通过定长报头的方式来解决的
请添加图片描述
其中数据是上一层应用层的数据,上面八个字节就是UDP的报头;
16位UDP长度是UDP报头的长度和数据的长度之和。所以提取数据时,要将16位UDP长度-8字节就是数据的长度;
如何分离:采用固定长度(8字节)的报头,将报头和数据分离;
如何交付:根据报头中的16位目的端口号,进行向上交付。

UDP如何提取完整报文?
先提取固定长度的报头,再用报头中的16位UDP长度-8字节就是数据总长度;这也说明UDP是面向数据报的。
UDP的特点

无连接:直到对端的IP和端口号就直接进行传输,不需要建立连接
不可靠:没有确认机制,没有重传机制,如果网络故障该段无法发送到对方,UDP协议层也不会给应用层返回错误消息
面向数据包:不够灵活的控制读写数据的次数和数量

面向数据报

应用层交给UDP多长的报文,UDP原样发送,既不会拆分,也不会合并。

例如UDP传输100字节数据,如果发送端调用一次sendto,发送100字节,那么接收端必须也要一次recvfrom,接受100字节,而不能循环调用10次,每次接受10个字节。
即:你发几次,我收几次

UDP的缓冲区

UDP没有真正意义上的发送缓冲区,调用sendto会直接交给内核,由内核将数据传给网络层协议进行后续的传输动作。
UDP具有接受缓冲区,但是接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致,如果缓冲区满了,再到达的UDP数据就会被丢弃。
UDP的socket既能读,也能写,即全双工

UDP注意事项

UDP协议首部有一个16位的最大长度,也就是说一个UDP能传输的数据最大长度是64k(包含UDP头部)
然而我们现在传输的数据超过64K时,就需要在应用层手动的分包,多次发送,并在接收端手动拼装。

基于UDP的应用层协议

NFS:网络文件系统
TFFP:简单文件传输协议
DHCP:动态主机配置协议
BOOTP:启动协议
DNS:域名解析协议

https://blog.csdn.net/weixin_47257473/article/details/132802268

TCP协议:传输控制协议(对数据的传输进行详细的控制)
TCP协议格式

请添加图片描述
源/目的端口号
32位序号/32位确认号:
4位TCP报头长度(表示TCP头有多少个32位bit);所以TCP头部最大长度是15 * 4 = 60字节;
6位标志位:

URG:紧急指针是否有效
ACK:确认号是否有效
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
RST:对方要求重新建立连接,我们把携带RST表示的称为复位报文段
SYN:请求建立连接,将携带SYN标识的称为同步报文段
FIN:通知对方,本端要关闭了,携带FIN标识的称为结束报文段

16位窗口大小:
16位校验和
16位紧急指针
40字节头部选项

必须回答的两个问题?

如何交付给上一层:TCP报文中含有16位的目的端口号
如何解包:TCP的报头是变长报头,因为有选项的加入,每次我们先提取20字节,根据4位首部长度得到整个报头的大小;规定4位首部首部长度的单位是4字节,这样4位首部长度能表示的范围就是0-60字节;由于报头最少有20字节,所以4位首部长度实际范围为20-60;
使用4位首部长度代表的字节-20字节就是选项的大小,然后解析选项,剩下的就是数据。

确认应答机制

理解可靠性

无论服务器还是客户端都无法保证最新发送数据的一方,发送的数据一定被对方收到;但在聚不上,可以做到百分百可靠。
TCP协议的确认应答机制:只要一个报文收到了对方的应答,就能保证我发送的数据对方一定收到了;

确认应答的机制

在TCP通信中,当发送方向接收方发送数据时,发送方会等待接收方返回的一个确认应答(ACK)来确认对方已成功接收到数据。
实现方式:序号和确认序列号保证了 响应应答针对的是那一条消息的应答。
序列号:TCP数据报中数据部分的第一个字节的序号,用于对数据进行编号和排序。
确认序列号:表示发送方期望下一个收到的字节的序号。
实现TCP的可靠传输和流量控制

1、保证请求和应答一一对应。
2、确认序号:确认序号之前的数据已经全部收到。
3、允许部分确认丢失或者不给应答:确认序列号可以丢一部分或者不给应答
4、为什么要有两个字段(序列号和确认序列号?)

发送的时候用的序列号,接受的时候是确认序列号。因为TCP是全双工的;如果不加以区分,发送数据和接收数据将会混在一起(比如发送方可能将接收方发送的数据当做一个应答)

5、如何确保顺序:报文中会携带序号,收到后会进行排序重组保证数据的顺序。确保顺序按正确的方式交付给应用层。

16位窗口大小:

16位窗口大小表示接收方在接收数据时的可用缓冲区大小。该字段指示了发送方在不需要等待确认应答的情况下,可以连续发送给接收方的数据的最大量。

缓冲区:TCP是全双工的,发送端和接收端都存在发送缓冲区和接受缓冲区,而UDP没有发送缓冲区。
流量控制:

接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送,就会造成丢包, 继而引起丢包重传等等一系列连锁反应.造成效率的下降。
因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control);
每次发送数据,接收缓冲区都会被填充,接收缓冲区剩余的空间大小变为16位窗口大小。

接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “16位窗口大小” 字段, 通过ACK端通知发送端;
窗口越小字段越大, 说明网络的吞吐量越高;
接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端,发送端接受到这个窗口之后, 就会减慢自己的发送速度;
如果接收端缓冲区满了, 就会将窗口置为0; 这时发送方不再发送数据, 但是需要定期发送一个窗口探测数据段, 使接收端把窗口大小告诉发送端.

6个标志位

在TCP协议中,TCP报文头中包含了一些标志位(Flags),用于在通信过程中传递特定的控制信息和状态

ACK:确认应答标志:确认应答时,该位置为1,大部分网络报文该标志位都为1;除了第一个连接时的请求。
SYN:建立连接请求:当SYN标志位被设置时,他指示发起连接的一方(通常是客户端)希望建立连接,并初始化序列号;
FIN:断开连接请求:当FIN标志位被设置时,表示发送方希望断开连接,不再发送数据。
URG:表示紧急指针字段是否生效:说明报文段中一部分数据被标为紧急数据,需要尽快处理;
PSH:表示接收方应该立即将数据交给上层应用而不需要等待缓存填满;
RST:重置连接;

16位紧急指针

16位紧急指针和URG标志位联系在一起。当URG标志位被设置时,代表紧急指针有效,表示该报文数据段中有部分数据被标记位紧急数据,需要尽快优先处理。
紧急指针; 紧急指针是TCP报文头中的一个字段,占用16位,用于指示紧急数据在数据段中的偏移量位置。它表示从报文的起始位置开始,紧急数据的偏移量.

超时重传机制

超时重传机制是在TCP协议中用于处理数据包丢失的一种机制。当发送方发送一个数据段后,会启动一个计时器(称为重传计时器),等待接收方发送对应的确认序号。如果在计时器超时之前未收到确认,发送方会认为数据包丢失,并重新发送该数据包。
数据包丢失会有两种情况:

一是发送方发送的数据丢失,导致接收方没有收到数据无法应答;解决:发送方重新发送数据即可;
二是接收方发送数据丢失,导致发送方收不到ACK,确认序号等信息。解决:由于接收方已经收到了数据,只不过他的ACK丢了,此时发送方会再次发送数据(数据重复),接收方会根据序列号进行判断,如果已经拥有,那么直接丢弃,就完成了去重。

超时时间设置

超时时间设置太长,影响重传效率,
超时时间设置太短,有可能频繁发送重复的包
TCP为了保证再任何环境下都能高性能通信,会动态计算这个最大超时时间;会重发多次,每次的时间成指数增长,累积到一定重传次数,若依旧没有应答,强制关闭连接;

流量控制

如何获得通信对方的接收能力?

在三次握手的时候,就会交换报文,得知对方16位窗口的大小;得知对方的接受能力
当对方缓冲区满时,已经不能再接受数据时,会用两种方式进行检测通知
1、每隔一段时间,发送方发送一个窗口检测的包,判断接收方的接受缓冲区能否接收数据
2、当接受方接收缓冲区已经可以接受数据时,会向发送方发送一个窗口更新通知,告诉对方已经可以发送数据;

滑动窗口

对每一个发送的数据段, 都要给一个ACK确认应答. 收到ACK后再发送下一个数据段.这样做有一个比较大的缺点, 就是性能较差. 尤其是数据往返的时间较长的时候.
一收一发性能比较低的话,那就一次发送多条数据,大大提高新跟那个(将多个段的等待时间重叠在一起)
如何控制发送的数据呢?

滑动窗口用于控制接收方和发送方之间的数据传输,他是一个动态的数据缓冲区,用于管理已经发送但未确认的数据序列号。
滑动窗口想要发送给对方多发送数据,又要保证对方来得及接受;
需要控制尽量多的数据但在对方的接受范围之内;滑动窗口的本质就是一次向对方发送可以接受的上限,
滑动窗口越大,网络的吞吐率越高,因为可发送的数据越多;
滑动窗口的窗口大小是由两个指针维护的;每次更新滑动窗口时:start = 收到的应答报文中序列号;end= start+收到的应答报文中的窗口大小;

几个常见问题?

1.每次滑动窗口必须向右移动吗?
答案是不一定。假设对方接收缓冲区一直不向上层交付,导致win_end一直不变,不会向右移动。
2.滑动窗口可以为0吗?
答案是可以,当win_start = win_end时,滑动窗口即为0.通常说明此时对方接收缓冲区是处于一种满的状态。
3.如果没有收到开始的应答报文,而是收到中间的,这可能吗,影不影响?
答案是可能,但不影响。首先中间确认报文中的确认序号保证了在此序号之前的所有报文都已经被成功接收。如果没有收到之前所有的报文是不会发送该确认报文的。

快重传

即收到3个同样的确认应答报文时立刻进行重发
那么既然有了快重传,为什么还要有超时重传呢,快重传不更快呢,为什么还要等?

第一,快重传是在连续收到三个相同应答报文后才触发的机制,如果我只发了两个数据段,那么就没办法进行重传了。
第二,我们的应答报文也有可能会丢失,造成无法及时重传。

拥塞控制

在发送端和接收端之间网络存在堵塞,在不清楚网络状况下,大量发送数据导致更加拥堵;
TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据
这里我们引用拥塞窗口的概念,拥塞窗口:单台主机一次向网络中发送大量数据时,可能会引发网络拥塞的上限值了。
所以此时滑动窗口值的大小不仅仅再是依靠对方的接收能力,还有拥塞窗口的大小。
滑动窗口的值是取 拥塞窗口 和 对方窗口大小(接收能力)的最小值。
发送开始时,定义的拥塞窗口大小为1
每次收到一个ACK应答,将拥塞窗口+1,然后取拥塞窗口和接收端的窗口大小的最小值作为实际发送的窗口值。
按以上的拥塞窗口增长速度,是指数级别的“慢启动”,初始时满,但是增长速度特别快.
慢启动存在阈值;
当拥塞窗口超过阈值后,不在按照指数增长,按照线性增长。
当TCP开始启动的时候, 慢启动阈值每次等于窗口最大值;
在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1.
少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为网络拥塞;
当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降;
拥塞控制, 归根结底是TCP协议想
1.尽可能快的把数据传输给对方 2.但是又要避免给网络造成太大压力的折中方案.

延迟应答

如果接收数据的主机 收到 数据后立刻返回ACK应答, 这时候返回的窗口可能比较小.因为此时上层没来得及接收。返回给对方的接收能力(16位窗口大小)会小。
我们要知道,网络传输中,单次IO的数据越多,吞吐量越高,效率就越高。
假设接收端缓冲区为1M. 一次收到了500K的数据; 如果立刻应答, 返回的窗口就是500K;
但实际上可能处理端处理的速度很快, 10ms之内就把500K数据从缓冲区消费掉了;
在这种情况下, 接收端处理还远没有达到自己的极限, 即使窗口再放大一些, 也能处理过来;
如果接收端稍微等一会再应答, 比如等待200ms再应答, 那么这个时候返回的窗口大小就是1M;
窗口越大, 网络吞吐量就越大, 传输效率就越高. 我们的目标是在保证网络不拥塞的情况下尽量提高传输效率.
那么所有的包都可以延迟应答么?
答案肯定不是,有两点:
1.数量限制:每隔N个包就应答一次。假设第一次来了一个包,我先不应答,来第二个包时,我再返回一个应答。在等待第二个包的同时给了将数据交付给上层的时间。
2.时间限制:超过最大延迟时间就应答一次。假设第一次来了一个包,然后过了一段时间,当然不能超过超时重传的时间,再给对方发送一个应答,在这段时间也足以让把数据交付给上层。
具体的数量和超时时间, 依操作系统不同也有差异; 一般N取2, 超时时间(不是超时重传的)取200ms

捎带应答

我们发现客户端和服务器基本上是一发一收。对于每一次发送和接收,都需要给对方发送一个ACK应答,但是每次如果只是单纯的发送ACK应答后,再发送数据,会造成效率低下。所以既然是发消息,我们直接把ACK捎带上即可。即把含有数据的报文中的ACK标志位设置为1.这样就只需要发送一次报文即可(我们前面基本一直是默认这样的)

理解面向字节流

创建一个TCP的socket, 同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区.

调用write时, 数据会先写入发送缓冲区中;
如果发送的字节数太长, 会被拆分成多个TCP的数据包发出;
如果发送的字节数太短, 就会先在缓冲区里等待, 等到缓冲区长度差不多了, 或者其他合适的时机发送出去;
接收数据的时候, 数据也是从网卡驱动程序到达内核的接收缓冲区;
然后应用程序可以调用read从接收缓冲区拿数据;
TCP只管把数据交给对方,至于如何解析这些数据,是上层应用层协议所做的事情,TCP只需要把数据安全可靠的发送给对方就好了。所以有了应用层的http协议等等。

三次握手

三次握手的目的就是为了确认通信双方的发收能力是正常的;
指定自己的初始化序列号位后面的可靠性传送做准备;实质上就是连接服务器指定端口,建立TCP链接,并同步链接双方的序列号和确认序列号,交换窗口大小信息。
我已得知三次握手的过程和为什么二次握手不可以,这里不在赘述;
半连接队列已经知道,不在赘述
ISN初始序列号是否固定已知,不再赘述
三次握手是否能够携带数据,已知
SYN攻击是什么?什么手段阻止?已知

四次握手

半关闭状态:发送关闭的一方是停止发送了,但是还可以接收;
四次挥手流程已知
挥手为什么需要四次?
其实也可以三次;
TIME_WAIT和2MSL已知
粘包问题解决

那么如何避免粘包问题呢? 归根结底就是一句话, 明确两个包之间的边界
对于定长的包, 保证每次都按固定大小读取即可; 比如UDP,报头中有16位UDP长度。可以根据这个来提取数据。
对于变长的包, 可以在包头的位置, 约定一个包总长度的字段, 从而就知道了包的结束位置;
对于变长的包, 还可以在包和包之间使用明确的分隔符(应用层协议, 是程序员自己来定的, 只要保证分隔符不和正文冲突即可);
那么UDP存在粘包问题吗?
答案是不存在的,正如刚才所说,UDP报头有16位UDP长度,可以明确数据的总长度,可以清楚的明确数据的边界。使用UDP的时候, 要么收到完整的UDP报文, 要么不收. 不会出现"半个"的情况。

三次握手、四次挥手的状态变迁图已知。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值