tcp与dup理解

使用socket进行数据传输
作为一个程序员,假设我们需要在A电脑的进程发一段数据到B电脑的进程,我们一般会在代码里使用sockte进行编程。

socket就像是一个电话或者邮箱。当你想要发送信息的时候,拨通电话或者将信息塞到邮箱里,socket内核会自动完成将数据传到对方的这个过程。

基于socket我们可以选择使用TCP或者UDP协议进行通讯。

对于TCP这样的可靠性协议,每次消息发出后都能明确知道对方收没收到,就像打电话一样,只要“喂喂”两下就能知道对方有没有在听。

而UDP就像是给邮箱的信箱寄信一样,你寄出去的信,根本就不知道对方有没有正常收到,丢了也是有可能的。

穿件socke的方式就像下面这样。

fd = socket(AF_INET, 具体协议,0)

注意上面的“具体协议”,如果传入的是SOCK_STREAM,是指使用字节流,说白了就是TCP协议。在这里插入图片描述
返回的fd是指socket句柄,可以理解为socket的身份证号。通过这个fd你可以在内核中找到唯一的socket结构。

如果想要通过这个socket发消息,只需要操作这个fd就行了,比如执行send(fd,msg,…),内核就会通过这个fd句柄找到socket然后进行发送数据的操作。

如果一切顺利,此时对方执行接受消息的操作,也就是recv(fd,msg,…),就能拿到你发的消息。
在这里插入图片描述
对于异常情况的处理
但如果不顺利呢?
比如消息发到一半,丢包了呢?
那UDP和TCP的态度是不太一样了。
UDP表示,“哦,是吗?然后呢?”
TCP态度就截然相反了,“啊?那可不行,是不是我发的太快了呢?是不是链路太堵被别人影响到了呢?不过你放心,我肯定给你补发”

TCP老实人石锤了。我们来看下这个老实人在背后都默默做了那些事情呢?

重传机制
对于TCP,它会给发出的信息打上一个编号(sequence),接收方收到后回一个确定(ack)。发送方可以通过ack的数值知道接收方接收到了哪些sequence的包。

如果长时间等不到对方的确认,TCP就会重新发一次消息,这就是所谓的重传机制。
在这里插入图片描述
流量控制机制

但重传这件事本身对性能影响是比较严重的,所以是下下策

于是TCP就需要思考有没有办法可以尽量避免重传

因为数据发送方和接收处理数据能力可能不同,因此如果可以根据双方的能力去调整发送的数据量就好了,于是就有了发送和接收窗口,基本上从名字就能看出它的作用,比如接收窗口的大小就是指,接收方当前能接收的数据大小,发送窗口的大小就指发送方当前能发的数据量大小。TCP根据窗口的大小去控制自己发送的数据量,这样就能大大减少丢包的概率。
在这里插入图片描述
滑动窗口机制

接收方的接受到数据之后,会不断处理,处理能力也不是一成不变的,有时候处理的快些,那就可以收多点数据,处理的慢点那就希望对方能少发点数据。毕竟发多了就有可能处理不过来导致丢包,丢包会导致重传,这可是下下策。因此我们需要动态的调节这个接受窗口的大小,于是就有了滑动窗口机制。
看到这里大家可能有点迷了,流量控制和滑动窗口机制貌似很像,他们之间是啥关系?我总结一下。其实现在TCP是通过滑动串口机制来实现流量控制机制的。
在这里插入图片描述
拥塞控制机制
但这还不够,有时候发生丢包,并不是因为发送方和接受方处理能力问题导致的。而是跟**网络环境*有关,大家可以将网络想象为一条公路。马路上可能堵满了别人家的车,值留下一辆车的空间。那就算你家有5辆车,目的地也正好有5个停车位,你也没有办法同事全部一起上路。于是TCP希望能感知到外部的网络环境,根据网络环境及时调整自己的发包数量,比如马路只够两辆车跑,那我就只发两辆车。但是外部环境这么复杂,TCP是怎么感知到的呢?

TCP会先慢慢试探的发数据,不断加码数据量,越发越多,先发一个,再发2个,4个…。直到出现丢包,这样TCP就知道现在当前网络大概吃得消几个包了,这既是所谓的拥塞控制机制

不少人会疑惑流量控制和拥塞控制的关系。我这里小小的总结下。流量控制针对的是单个连接数据处理能力的控制,拥塞控制针对的是整个网络环境数据处理能力控制。
在这里插入图片描述
分段机制
但上面提到的都是降低重传的概率,似乎重传这个事情就是无法避免的,那如果确实发生了,有没有办法降低它带来的影响呢?

有。当我们需要发送一个超大的数据包时,如果这个数据包丢了,那就得重传同样大的数据包。但如果我能将其分成一小段一小段,那就算真丢了,那我也就只需要重传那一小段就好了,大大减小了重传的压力,这就是TCP的分段机制。

而这个所谓的一小段的长度,在传输层叫MSS(Maximum segment size),数据包长度大于MSS则会分成N个小于等于MSS的包。
在这里插入图片描述
而在网络层,如果数据包还大于MTU(Maximum Transmit Unit),那还会继续分包。
在这里插入图片描述
乱序重排机制

既然数据包会被分段,链路又这么复杂还会丢包,那数据包乱序也就显得不奇怪了。比如发送数据包1,2,3。1号数据包走了其他网络路径,2和3数据包先到,1数据包厚道,于是数据包顺序就变成了2,3,1。这一点TCP也考虑到了,依靠数据包的sequence,接收房就能知道数据包的先后顺序。

后发的数据包先到是吧,那就先放到专门的乱序队列中,等数据都到齐后,重新整理好乱序队列的数据包顺序后再给到用户,这就是乱序重排机制

连接机制
前面调到,UDP是无连接的,而TCP是面向连接的。
这里提到的连接到底是啥?

TCP通过上面提到的各种机制实现了数据的可靠性。这些机制背后是通过一个个数据结构来实现的逻辑。而为了实现这套逻辑,操作系统内科需要在两端代码里维护一套复杂的状态机(三次握手,四次回收,RST,closing等异常处理机制),这套状态机其实就是所谓的“连接”。这其实就是TCP的连接机制,而UDP用不上这套状态机,因此它是“无连接”的。

网络环境链路很长,还复杂,数据丢包是很常见的。

我们平常用TCP做各种数据传输,完全对这些事情无感知。

哪有什么岁月静好,是TCP替你负重前行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值