tcp协议记录

一.概述

在互联网时代,整体的服务都是通过网络进行。网络如果出现瓶颈也会影响服务体验,更严重的会导致服务不可用。

了解网络也是能够在搬砖的工作中,能够识别一些坑,并在出现问题的时候能够较快的定位。

二.tcp/ip协议分层

一般有7层协议,四层协议。

用的比较多的是四层协议,这个协议也是我们大多数人关注的。

四层协议发送与接收详细每层数据结构:

在这里插入图片描述

可以看到上层复用下层能力,发送的时候从上层往下依次将数据包装,接收的时候则依次解封。如应用层是http协议往传办理层提交数据,传输层会加上自已的数据规范=tcp首部(传输层数据)+http数据。

三.tcp协议

1.tcp三次握手连接

客户端与服务器通过三次握手进行连接,图如下:

 这里为什么是3次,而不是2次或1次。这个本质上是一个概率问题。

3次能保证刚好客户端与服务端都有请求与响应。一定程度上确定了网络及双方服务的可用性。

2.tcp四次握手关闭

 这里有time_wait状态主要是是以下2点考虑:

a.让客户端的响应有机会重试,因为客户端在第4步响应服务器的时候可能出现丢包,所以需要有时间做重试。

b.在客户端关闭连接后,后续又重用了这个端口,网络上的包有可能由于网络原因后面又到达了这个端口。此时如果时间很短就会导致这些包是这个新连接的。

3.tcp要解的几个问题

tcp从参与者来看,有:发送方,网络媒介,接收方三个角色。

滑动窗口解法乱序,重传及接收方处理不过来的问题。

拥塞窗口解法网络阻塞问题。

而在整个网络交互过程中会有以下几个问题:

a.乱序

即发送方发送了a,b两个包,接收方可能接收的顺序是b,a。

策略:

定义包id,自增,接收方确认的时候根据包id顺序确认。同时接收方应用层根据这个id来进行确认,如果出现发送方发了1,2,3三个包,接收方接收到了1,3,这时接收方只能确认1.

b.包超时

发送方发送包时,由于网络或接收方问题会出现包的超时。

策略:

超时重传。

超时重传的策略有

发送方定时超时重传:这个可以采样网络rt,计算平均rt。

接收方对于未收到的包重发3次期望接收的ack。

接收方将已接收地图发给发送方,由发送方判断,如已接收1,3. 这样发送方就知道2丢了,要重发。

c.接收端处理不过来

接收端处理不过来,一般是发送方发送太快。

d.不能将网络整个塞满

这个一个解法就是碰到丢包问题,就将拥塞窗口减小。

tcp一般会减少原先窗口的n/2. 然后后续每收到一个包就加1.

这个解法缺点也很明显,即网络带宽可能是好的,但是少数包丢失是因为接收方问题,造成了误判。另外一方面在出现丢包问题时,多余的包可能已经将网络中中间设备填满了,这时整体网络环境已经很糟糕了,太迟了。

另一个解法就是用tcp的bbr算法。

4.socket编程

服务端与客户端通信,要经过连接,收发数据,关闭三个生命周期。

相应双方交互的流程图:

服务器与客户端交互是一个四元组:客户端ip及端口,服务端ip及端口。

这里需要注意的是一个客户端连接和后续的读写是2个socket,服务器端就是2个文件描述符。这么做原因是整体按socket的生命周期去看,连接属于一个连接范围的功能,后续读写切开去看,职责相对比较内聚。

而服务器理论上能够打开socket的数量是:2的48次方。

但由于服务端采用的io线程模型是哪个方案,会决定到底数量是多少。

如果是同步阻塞的io模型,由于每个客户端过来连接都需要一个线程,因此这个上限取决于操作系统能够创建的线程上限。

如果是同步非阻塞io复用,selector模式:则上限是1024. 这个是由于每个服务器端口监听的socket都会放到一个fd_set文件描述符数组中。这个模式还有缺点:每次都需要将fd_set从内核拷到用户态然后selector线程再看哪个事件就绪了。性能差。

在selector后面,出现了epoll。epoll是同步非阻塞,但优化点在于要监听的socket不存数组了,而是会新建一个epoll文件描述符,这个文件描述符会指向一个红黑树,红黑树每个结点就是要监听事件对应的socket。这样即解决了fd_set数组1024上限的问题,也解决了查询哪个socket有事件的性能问题,并且不用拷贝完整的socket监听对象到用户态。

epoll图:

5.常见问题

  • tcp time wait在哪个端?有什么问题?怎么解?

在关闭发起方,通常是客户端。问题会是出现大量的time wait导致客户端无可用连接。

解法:优先长连接,tcp_tw_recycle(不建议,NAT情况下会导致连接失败),tcp_tw_reuse。

tcp_tw_recycle问题是在NAT网络下不同客户端使用同一个IP,而不同客户端时间不一样就会导致客户端B连接不上(由于客户端A用了这个连接,时间又比B慢)。

tcp_tw_reuse则是限制只会重用time wait状态且到time_wait状态时间超过1秒的连接。本质上是减少概率发生。

  • tcp为什么是三次握手,不是二次,或四次。

2次:超时情况下会会建立多个无效连接死锁情况。多余无效连接:例:客户端发起连接sync包,超时后客户端再发起一个sync。但由于只是二次握手此时服务端建立了2个连接。死锁例:服务端收到sync就建立好连接开始传数据,但由时客户端还没收到服务端的ack此时客户端会丢弃这些包,但服务端认为超时会重发。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值