美文网首页
[081]由TCP/IP协议想到的思想

[081]由TCP/IP协议想到的思想

作者: shawnxjf | 来源:发表于2017-10-14 23:14 被阅读0次

    TCP/IP协议场景

    说道TCP/IP协议想起了计算机网络书中举了一个红蓝军的通讯的问题。其场景如下:

    红蓝军需要联手干掉山坡下敌人,双方约定某个时间一起进攻。

    红军 <-------------> 蓝军

       -----A:下午5点进攻-->
       <---A+ack:收到消息---
       -----A+ack+ack:----
    

    由于任何一次通信都可能中断,通讯次数越多概率越大。于是在通讯可靠性和时间上做了一个折中,根据理论计算至少需要3次握手概率才达到比较满意的水平。

    TCP协议本质上解决是不可靠信道上需要可靠传输信息的需求

    如果信道是可靠的那么,那么不需要建立连接直接发送数据包也能够确保到达。但是实际网络中信道是不可靠的,需要通过3次握手来确定一条比较可靠的信道。

    所以TCP连接建立后,都是沿同一条链路发送消息么?

    连接释放为什么需要4次握手

    通过4次握手的目的是确保通信双方都释放了连接,这样都不在发送数据包(防止网络上有大量的无用数据包,会增加网络的拥塞)。

    TCP 序列号和确认号详解

    TCP 通讯涉及到 客户端 client 和服务端 server,我们根据建立连接、发送数据、释放连接 3个阶段来描述序列号和确认号生成过程。

    连接建立阶段大体上是,确认号=对方的序列号+1,序列号(除了第一次)=对方的确认号
    客户端 服务端
    序列号J | 确认号0 |置SYN标识 ---->
    <---- 序列号k | 确认号J+1 | 置SYN和ACK标识
    序列号J+1| 确认号 k+1 | 置ACK标识 ---->

    数据传输阶段大体上是,确认号=对方序列号 + 数据报文长度,序列号= 对方确认号

    TCP 协议的状态迁移

    TCP建立连接一般是服务器启动服务进行监听,处理客户端发过来的请求。
    其状态流转是:
    client:close -> SYN-SEND -> ESTABLISH
    server: close -> LISTEN -> SYN-RECV -> ESTABLISH

    连接释放,我们以客户端主动断开连接为例。
    客户端 服务端
    发送报文 FIN_WAIT1 --> 此时服务器 CLOSE_WAIT(被动关闭)
    FIN_WAIT2 <-- 服务器 ACK到客户端
    TIME_WAIT (接收到最后确认后,客户端进入TIME——WAIT) <--- 再一次确认 LASTACK
    当客户端等待2MSL后 发送ack 到服务端 --> close状态了

    实际连接释放可以分为两个阶段,第一阶段:半连接 ,第二阶段:服务端也释放。
    第一阶段:
    客户端 发送fin报文 ---> 服务端
    FIN_WAIT2 <---- ACK 报文
    FIN_WAIT2 状态就是半连接的状态,表示客户端已经断开连接,服务端还有一些数据要发送。

    第二阶段:
    过了一段时间,服务端没有数据要发送了。
    此时:
    TIME_WAIT <--- 服务端发送FIN 报文 进入LAST_ACk状态 (服务端在发送了FIN后等待 MSL如果没有收到ACK则会重传FIN消息)
    客户端发送 ACK ---> 服务端
    客户端发出ACK后,等待ACK到达对方的超时时间MSL,等待FIN重传时间也是MSL,所以如果客户端2MSL时间段内没有收到FIN报文表示 服务端已经收到了ACK报文(已经关闭了)。

    用概率来衡量不确定的东西

    从“背景”那里分析,握手次数越多越好概率越高。但是实际情况下是可靠性和时效性之间的折中。而对于这些不确定的事情,我们最好的思路是以概率的方式来思考(而不是强迫症似的想100%)。

    同样在微服务框架中,通过两台机器提供负载均衡。这样系统可用性为 p = 1-p1*p1,p1为系统宕机的概率。

    思想的运用

    TCP/IP 会有超时重传的机制,每发一段报文的时候会设置一个超时时间,如果超时会重发报文。

    在我们的支付系统中,系统与系统之间的交互也是类似的思想。拿下单来举例:
    网关 client .................... server 银行(比如支付宝)
    ewallet 下单 ---> 发报文到银行
    <--- 同步返回/或者异步通知 (ack) ,如果client timeout内没有接收到ack报文,则通过定时任务扫描网关中非success 的订单,调用查询接口(查询状态)。
    ---> response.write("success") (ack+ack) ,同样,如果server没有收到ack+ack 报文,则会重传 ack报文(即重新异步通知)。

    参考:

    http://www.cnblogs.com/chenboo/archive/2011/12/19/2293327.html

    相关文章

      网友评论

          本文标题:[081]由TCP/IP协议想到的思想

          本文链接:https://www.haomeiwen.com/subject/qmxquxtx.html