首发于 java
传输层,tcp、udp计算机网络(中)

传输层,tcp、udp计算机网络(中)

传输层:

上面说到网络层是 主机到主机之间通信。 应用层更细化点 主机中的进程到主机中的进程之间的通信(端口对端口) 传输层就是为应用层某进程对应的端口提供传输服务(tcp、udp)。

而应用层对应多个进程,每个进程都可能对应不同的协议,如果交给传输层,去一个个传输,就比较复杂,传输层为解决这个问题,采取了复用技术(即 合到一起传输),之后到了目的主机,由传输层,采用分用技术(分开 提供服务给上层)。

端口:16bit

作用,主机中某个进程交互时网络层通过ip定位到主机,传输层通过某个端口 对应到相应进程,为应用层提供服务,最终实现了交换,端口就是为了更细化点,对应到某个主机中的某个进程。

ok 继续回到传输层协议,主要有两个协议 tcp udp

1.UDP 用户数据报协议

上图可以看到udp数据包首部只有简短的8个字节

上面的伪首部是什么? 因为udp字段太简单了,检验和检验只能检查 源端口,目的端口,长度,每个主机都可能是这样,重复几率太大,借助一个伪首部,这样,就可以通过伪首部中的源ip,目的ip,等字段,这样检验和检验时通过伪首部+本来的首部一起算检验和。这样算出来的值就有唯一性了。 ps:伪首部只有算校验和的时候会用到,在交付给网络层会扔掉,因为ip中已经有源ip,目的ip等信息,会冗余。

2.TCP传输控制协议

面向字节流概念:

发送方进程发送的数据块和接收方进程接受的数据块,可能大小不一样。但是从字节流的角度考虑,他们最终接到的字节流肯定是一样的。

ps:

现在我们俩看看tcp首部,首先tcp为了保证可靠传输,肯定字段比较多,一看图,确实是这样。

首先

  1. 源端口,目的端口各2个字节
  2. 序号 seq 对每个字节的编号,例如 发送方发了1000个字节, 对每个字节编号。
  3. 确认号 ack 对序号的确认,和要求下次发送方从什么时候开始。 eg.A给B发了个seq=10,B收到了,回来个ack=11,要求A下次seq=从11开始发。同理如果A,B同时对发数据的时候,A给B发了个 seq=10,ack=21,B收到了就知道一次发送从seq=21开始,回了ack=11,就是要求A下次 seq=11,开始发送,是相互的!
  4. 数据偏移 4bit 一位是4个字节,数据和头部起始的距离,可以知道数据是从哪个字节开始。
  5. 一些标志 各1bit

6.窗口 2分字节 告诉对方 字节的窗口是多少,这样发送方就知道发送多少数据了。 7.检验和 和UDP一样 需要有个伪首部,不然只凭借前面的字段无法具有唯一性。


tcp可靠传输原理

其一 停止等待协议

发送方 发一个分组 等待 接受方返回一个ack ,发送方收到ack,才继续发送。

A发送方 B接收方

如果 分组中途丢了,B没接到,或者B经过检验发现错误丢弃了,亦或者B回的ack 丢了 ,那A怎么办?

A为了解决这种情况 有个

超时重传机制 :A每发送一个分组 内部有个超时计时器,等计时器到时间了还没收到ack,就会继续重发。

PS

1.A发送时候,应该保留备份,已备重发。 2. A,B对分组,ack得有编号,不然不确定ack的是哪个分组 3.超时计时器设计时间应该略大于 平均往返时间,不然 ack没回来,一直重新计时。

上面的也称为自动重传请求ARQ 接受方不需要告诉发送方需要重传哪个分组,重传是自动的。

但是上面有个缺点,每次都要等到接收方确认才可以继续发送,信道利用率低,发送方很长时间都在等待确认了。

所以出来了 连续ARQ协议 也称滑动窗口协议

发送根据滑动窗口的大小一次给 接收方 发好多,接收方根据自己的滑动窗口大小去接收,接收方只需要回答最后一个ack(如果回答了8的ack 代表8前面的都接收完成)

好处:不用阻塞太久,即使发送方 没收到 8前面的ack,只要收到了8ack,就代表8前面都ok。不用重传了。

坏处:因为是只发送最后一个ack,如果1-5中5的ack OK 6-10, 其中8的出错了,接收方丢弃了,此时 不能给发送方回应 10 ack ,只能找到最后一个ack,如果是6的ack,那么就会从7开始,重新发7-10.也称回退N,不一个个确认,所以不知道具体是哪个出错,只知道是7-10这段出错。

tcp 通信具体实现

1.发送方 接收方都有一个窗口,发送方,缓存报文用,之后给发出去, 接收方窗口,缓存排序用,如果1,3,4,5 没收到2,他会等2到达排好序在提供给应用层

2.他们是基于字节序号来确认的,并不是基于报文段

3.tcp接发窗口是动态的 拥塞控制,流量控制有关

4.往返时间RTT也会根据某些算法动态调整的。


滑动窗口

首先发送放从发送缓存中 拿到数据,发到发送窗口中,发送窗口会根据接收方的返回 窗口大小动态改变。(因为如果你一下发报文太大(一个个字节),接收方的接受窗口有限,你发了也接受不了)

接收方接到报文,解析成字节放到缓存窗口里,等到达一定数量,排好顺序!再一起提供给接受缓存。发送方发送的字节,在没有得到接收方的ack之前是不会丢掉的,不然,接收方要求重发的时候,字节就没有了。

发送方,接受方的窗口不一定是同步的,如果接受放本来接受窗口为30,此时发送方也变为30了,突然接收方,变为10了,如果此时发送方窗口中的字节还没有被确认,他是不会直接抛弃掉20个变为10的,需要慢慢变小,可能30-25-20-15-10,不会直接扔掉变小!

滑动窗口

还有一个重要因素就重传的时间

平均往返时间RTT

如果RTT太大,网络空闲太久,信道利用率低

如果RTT太小,数据并没有丢弃,而是在路上,这时候就重发,造成网络负荷。

而且用平均值,某时刻网络比较拥塞,他的RTT就会高于平均值,这时候如果要求重发,也会造成网络负荷。

所以出来个加权平均往返时间RTTs

RRT取1/8刚刚网络rtt,7/8 旧的网络RTT。所有大概念取决于之前的往返时间,虽然只有1/8的是意外情况,但是在网络变动时,RTTs更容易变为最新的网路状况的Rtt时间。

还有其他算法入RTO,karn就不深入了

扩展 :SACK ,首部扩展字段中可以选择,在建议连接之前就规定使用才行,在之前累积确认我们发现了,如果200-300之前只有其中某一段字节丢了,我们需要全部重发,能不能单一确认了,用SACK,一个个确认,只要收到了sack就不需要重发了,没收到才重发,但是一般出错都是某段边界减去前段边界,得出的还是某一段,还需要一个个发sack,实际上用的并不多。

一般来说我们想让数据发的快一点,但是如果接收方来不及接收,就会造成数据的丢失。

流量控制 就是让发送方发送的不要太快,既要让对方来得及接收,也不要让网络造成堵塞。

实现主要靠滑动窗口,接收方会根据自己的窗口大小,告诉对方,让发送方知道发送数据的大小,实现流量控制。

但是如果 接收方rwnd=0,发送方,收到了rwnd=0,如果数据发完了且都得到ack 了 他也会把rwnd掷为0, 此时接收方ok了,rwnd不等于0了,会告诉发送方,这样发送方就将rwnd改变,继续发送数据! 如果接收方这条消息没有发送过去呢! 那发送方一直为0 接收方也在等待发送方发数据! 这样会造成死锁

为解决这个问题 tcp 提供一个 持续计时器(persistence timer)不是超时重传那个计时器。 当某一方接受到对方的 零窗口通知时,在其内部维护了一个持续计时器,如果到时间了,还是没有收到消息,他就会向对方 发送方一个零窗口探测报文(数据部分只有1个字节,头部还是最少20个字节),如果收到rwnd还是0 他就重新计时,如果不为0,死锁问题就解决了

TCP如何 控制报文发送时机

1.内部维持一个变量,等于最大报文长度MSS,当达到MSS时发送。

2.内部维持一个计时器,时间一到就发送,发送报文长度也得小于MSS

3.接受到PSH标志,立刻发送


拥塞控制

当某一时刻对网络 某资源的需要量 大于 该资源所能提供量会出现网络拥塞

拥塞控制就是 防止过多的数据注入到网络,使网络中的路由器或者线路不至于过载。

拥塞控制和流量控制的区别

拥塞控制是一个全局的过程,包括传输线路上的所有的主机,路由器及降低网络性能有关的因素。

流量控制 主要是 接收方和发送方之间 保证接收方的接受大小,和发送方的发送大小的关联。


可以看到 在网络上,随着数据的变多,刚开始吞吐量会越来越大,达到某值时,吞吐率减少,吞吐量还是在增加,趋势变缓,直到某一时刻,吞吐量,不增反降。所有拥塞控制非常重要。前期进行了拥塞控制反而下降了 是因为有一些限定条件 确保整个阶段都可以提高导致。

tcp也是基于窗口来实现 拥塞控制,cwnd拥塞窗口:发送方会根据当前网络状况动态的去调整大小,控制注入网络中数据的量,以保证网络不过载。

之前收到的rwnd是 根据接收方的窗口大小,来保证发送合适的数据,保证接收方不会因为接收不了,丢失。 现在拥塞控制 cwnd是发送方根据当前网络情况,来控制注入网络的数据量。所以 实际发送的数据得综合这两个因素 实际发送窗口值(snwd)=Min(接收窗口rnwd,拥塞窗口cnwd)

控制拥塞原则:

拥塞判断

  1. 超时重传计时器:现在通信传输质量一般都比较不错,(传输丢失概率很小),所以出现了重传,我门就认为当前网络,可能已经出堵塞了。
  2. 收到了3个ack(重复),某段时间收到了重复的ack,之后分组ack正常,预测可能要出现拥塞了(实际还没发生堵塞),因此尽快采取控制。

TCP拥塞控制算法

刚开始慢启动,让发送方cnwd从1开始增加 2的指数 1-->2-->4-->8-->16达到设置的某值后,进行拥塞避免让他1个1个加到ssthrsh 门限值,这样的好处是,如果16直接到32可能堵塞了,就需要回到1或者回到某值重新开始。这工程中只有16+32=48 而如果16之后慢慢加16+17+18+19...+32,中途某时刻,出现堵塞了,最终传输的数据后者明显多于前者

ssthrsh 门限值初始为16,如果遇到超时重传变为上次,超时重传时cnwd一半的大小,eg图上为12

到图上第4个点时,可能某报文丢失了,eg。1,2,3,4,5个报文,2丢失了,3,4,5是ok的,之前都是等接收方,发送数据的时候,捎带确认,采取快传重后:一个不按顺序的数据段,发送过来,接收方会立刻重发ack,收到了3,回个ack=2,收到了4 回个ack=2,收到了5回个ack=2,这样一来收到了3个重复的ack,发送方,就立刻重传,这样就不会等到超时了,超时回到1,之后慢启动,而3-ack之后 看图,只需要回到一半的ssthrsh,比之前恢复速度快,(快恢复)。

PS:超时是网络已经发生了重大堵塞,而3-ack是提前预测可能出现堵塞了。所以对到超时比较严格,cwnd需回到1,然后慢启动,而3-ack是提前预判,只需要回到当前一般的cnwd,之后采拥塞避免算法,恢复比较快。

因为拥塞控制是一个全局的过程,这里只是端双方,还有路由器处理

随机早起检测red: 路由器内部有有几个处理数据原则。 数据<最小门限 ,网络完全ok,还能处理更多数据,所有此时还让数据进来,

最小门限<数据<最大门限 随机丢掉一些数据,这样会出现3-ack,cnwd变为1半,提前预警拥塞。

数据啊>最大门限 后达到的数据全部丢弃,会出现重传情况 cnwd变为1。

为什么不直接等超过了最大将后面的数据全部丢弃,这样可能一段时间后,后面数据又同时过来,造成拥塞,所以采取随机丢弃,错峰来数据的情况。

现已被废弃,被AQM主动队列管理算法代替 对路由器中分组队列进行智能管理,而非简单的丢弃。


tcp为什么要建立连接?

TCP三次握手

首先C先发送SYN=1,seq=x seq是第一次根据主机某算出来的,并不是从1开始。

S回应 SYN=1 ACK=1,seq=y 也是某个值,ack=x+1,上次C seq=x,所有这里ack=x+1,让他下次从x+1开始发。

C回应 ACK=1,上次回的ack=x+1,所以seq=x+1 ,上次S,seq=y,所有这里ack=y+1

问题一:为什么是三次握手?

全双工角度,两边都能通信,才成功。如果没最后一次握手,C 发了SYN建立连接,S 回应了,并且发出SYN C-->S C知道可以连接了, S发的SYN C没有回应,他也不确定S-->C 这个方向有没成功。所有需要C给他回个ack,S才知道C收到了 S-->C这个方向也连接成功

安全角度,如果C发一个 S回应了,就建立成功。之前失效的连接或者错误的连接过来了,S就与他们连接,而他们是失效的或者是错误请求,(后来通过重发,已经连上了,之前的已经不需要了) S不知道,就连上了。一直没有请求发送,会占用S端资源或错误,严重情况下可能导致服务器奔溃。又或者S给C的回应丢了,S不知道以为建立成功了,就给C发送数据,C还没建立连接,一直等到S的ACK报文,就把数据丢弃了,S一直重发,严重占用网络资源。

问题二:如果连上后client端 宕机了怎么办?

服务端有个保活计时器,每收到client端请求后,会设置一个计时器,通常为2小时,如果2小时还没有收到client请求,服务端就会 每隔75s就会向client发送一个探测报文,判断client是否还活着,如果10次,client还是没回,S认为client端死了,就会关闭连接。

TCP四次挥手

和上面的类似,不同在第二个,Server端回应Client端,我还有数据没发完,稍等,等数据发完了第三次才回FIN表示可以关闭连接了,client端回一个ACK,变为TIME-WAIT状态等2MSL之后关连接。

问题一:为什么建立连接要3次,断开要4次呢?

实际上建立连接也是4次,只不过第二次 Server端回了一个ACK+SYN,这样应答和SYN同步一起回给了Client端,而断开时,Server端数据还没发好,此时不会立刻回一个FIN+ACK,所以先回了一个ACK,之后等数据发完,再回个FIN,所有就变为了4次。

问题二:为什么需要2MSL呢?

  1. 当Client发了数据,他不确定,Server有没有收到,如果直接关闭,Server收不到ack会一直重发,连接无法关闭,为2MSL:Client发ACK最大1MLS+Server重发最大1MSL,确保Server没收到ACK来得及重发并且数据达到Client端。
  2. 当两端都关闭,等到2MLS,可以确保,当前连接中的所有请求都失效,(Client发ACK最大1MLS+Server重发最大1MSL,如果小于2MSL,后面Server的请求可能还在传输),下次建立连接时,不会有失效的报文请求。

问题三:为什么TCP最后一次应答不要等待?

哈哈。其实Client一直在等待,因为他本来就是为了建立连接,就一直在那,所以即使Client发的ACK Server没收到,Server重发一个,Client收到后再回一个。



参考: bilibili.com/video/BV1y

深圳SEO优化公司雅安设计网站凉山设计网站推荐兴安盟网络营销镇江网站设计模板公司通化营销型网站建设公司通辽外贸网站建设报价和田模板网站建设报价呼和浩特百度seo眉山seo网站推广公司唐山模板制作推荐广东百度标王多少钱徐州建站报价云浮外贸网站设计推荐扬州外贸网站制作推荐永州企业网站建设贵阳百度网站优化排名公司莱芜SEO按天收费哪家好那曲网页制作哪家好湛江网站优化按天收费哪家好南平建设网站公司梅州seo排名推荐廊坊seo网站优化推荐昌吉seo价格大丰网站seo优化价格柳州网站推广系统公司潜江建设网站公司四平seo网站优化报价广安百度网站优化排名价格汕尾模板推广多少钱南宁阿里店铺托管歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化