TCP 协议的相关特性

发布于:2024-06-06 ⋅ 阅读:(82) ⋅ 点赞:(0)

一些TCP协议的基础标志位:

URG:紧急指针是否有效

ACK:确认号是否有效

PSH:提示接收端应用程序立刻把数据读走

RST:要求重新建立连接,也叫复位报文段

SYN:请求建立连接,同步报文段

FIN:通知要断开连接了我这里,结束报文段

一,确认应答

这是核心机制,但也比较简单,也就是你发送过去了一个数据是(1-1000),那边确认应答之后,给你回了一个(1001),就是告诉你下一个数据的开始序列是那个,也是这边确认收到了的意思。(确认应答也是ACK)

图:

二,超时重传

就比如你发送了一个消息,别人一直没有理你,你这边就想着是不是没有收到啊,再发了一次,这也就是超时重传。

也就是主机A这边发送了一个消息,在一个特定时间里面,主机B的确认应答一直没有发送过来,就会进行重新发送,以确保数据不会出现丢包。

但要注意的是也可能出现ACK丢失的情况,就会重复发了一段。这时候就需要去重了,接收方这边有一个数据结构叫做数据缓冲区,当有数据进入这个区,应用程序以read,就会把这个重复的从缓冲区删掉。

三,连接管理

 分为建立连接和断开连接,

建立连接:三次握手:

也就是通信双方要互相保存对方的信息,具体完成需要三次网络交互。

首先发起请求方先发一次 同步报文,接受请求方在接受到了之后,向客户端发一个同步报文(SYN)+应答报文(ACK),在接受到服务器发的SYN+ACK之后,客户端这边在发一个应答报文(ACK)。

建立连接的意义:

投石问路,确认当前通信路径是否通畅。

协商参数,确认一些通信中必备的通信参数

具体做法是这样的:

 断开连接也就是四次挥手,也就是客户端这边给服务器这边发送一个FIN(结束报文),进入了一个time_wait状态,如果出现大量的这个状态,就证明服务器触发了大量的主动断开TCP连接操作,服务器这边回一个(ACK)应答报文,这时服务器会进入一个close_wait状态,如果出现了大量close_wait状态,那就可能应用程序忘记调用close了,等客户端这边的应用程序代码执行到close的时候,再发一个(FIN),在客户端这边收到之后,就给服务器发一个ACK,告诉服务器我这边结束了,不要再联系了。

具体情况时这样的:

四,滑动窗口

这个好理解,在上面传输数据的时候,都是一个一个往过传输的,效率很慢,所以就需要一个加快传输效率的方法,滑动窗口就出现了,也就是把很多条数据一起发送过去,这样就降低了等待时间。

具体实现:

这边发送前五条数据的时候,不用等待ACK就直接发送。

窗口大小代表着继续发送数据的最大值,这边的就是4000

收到第一个ACK后就继续发送第五个数据以此类推 

注意问题:

第一个,返回的ACK 丢了咋办,这个没事,后面还有一直跟着返回的ACK,客户端这边还能继续确认,不影响什么。

第二个,数据包丢了,比如第二个数据包2000丢了。这边ACK返回的全都是下一个是1001 ,如果客户端这边收到了三个这个,就会重新发送1001~2000这个数据包。这边接受到第二个数据包之后,直接返回的就是给你发的那个最后卡住的地方,前面的值已经接受到了,在接收缓冲区。这种机制也叫做高速重发控制(快重传)

拿图表示:

五,流量控制

接收端这边处理数据是有限的,如果接收端这边满了,发送端再发数据就很容易造成丢包,引起丢包重传的低效操作。

因此接收端这边就会把自己可以接收的缓冲区的大小放到TCP首部,也就是窗口大小,窗口越大,接收的数据越多,效率就越高,反之则越低。

一旦这边窗口满了,就会告诉客户端那边停止发送。

上图:

六,拥塞控制

和流量控制类似,都是启动了滑动窗口来进行控制,也就是站在接收方的角度,影响这发送方的速度,也就是一开始让你先发点,看没有丢包就继续加,加到窗口大的很,开始丢包了,就赶快减少,减少到不丢包为止,也就是在丢包的边缘疯狂试探。

上图:

七,延时应答

也就是ACK不会立即返回,会等一段时间再返回,这样也是为了提高传输效率,比如现在窗口的大小是5kb,这边传过来一个1kb的数据,如果立即返回ACK,那过去的窗口大小只有4kb,等一会应用程序可能把1kb的数据消费了,这是返回ACK就有5kb了。

此处延时有两种方法:

一种是按照一定时间来延时

第二个是按照接收到的数据量。

八,捎带应答

建立在演示应答基础上的提高效率的方法:

比如在客户端这边一般都是一问一答机制,但在延时应答的时候,ACK 等了一会会,这是给客户端的请求,ACK正好可以捎带着一起返回了,可以提高效率

九,面向字节流(粘包问题)

在字节流  读写数据的情况下,会涉及到一个很严重的问题,也就是粘包问题。

就比如你一次发送了好几个单词,比如dog,cat,hello。你发过去后,由于字节流,就可能一次读一个字节或者若干字节,所以可能给你读成dogcathello这种了。

此处粘的主要应用层的数据包,也就是要区分一个到一个应用层数据包之间的界限。

主要用两点:

1)使用分隔符,任何字符都可以,只要在数据中不存在的都可以

2)约定包的长度

十,异常情况

1)进程终⽌:进程终⽌会释放⽂件描述符,仍然可以发送FIN.和正常关闭没有什么区别.

2)机器重启:和进程终⽌的情况相同。

3)机器掉电/⽹线断开,接收端认为连接还在,⼀旦接收端有写⼊操作,接收端发现连接已经不在了,就会进⾏reset,即使没有写⼊操作,TCP⾃⼰也内置了⼀个保活定时器,会定期询问对⽅是否还在,如果 对⽅不在,也会把连接释放。


网站公告

今日签到

点亮在社区的每一天
去签到