tcp 协议通俗解释。

----------------------------------------
tcp 协议通俗解释。
----------------------------------------
话说红蓝军对抗,红军中两个小分队A、B要同步信息好一起发起攻击,但是AB间信道不稳定(有蓝军干扰),
问A、B怎样才能确定将信息发送到了对方? tcp 协议就是一种在不稳定的网络条件下,保证稳定通讯的协议。
它的稳定措施是确认和重传机制。
 
----------------------------------------
1. tcp 协议
----------------------------------------
tcp 协议是一个可靠的连接协议,在数据发送过程中,需要对方的确认
就好比打电话时,A 滔滔不绝的讲,必须得到 B 回应 "嗯“,”讲的好","我听着呢".
如果B 不回应了,A 就知道出问题了,要重传刚才的数据,如果连接断了。就不用再发送了。
就是说,tcp 通讯是双向的,通讯过程要收到对方确认。
 
在IP层,从A点到B点,和从B点至A点是走不同的路由的,所以双方都要确保路径畅通
 
----------------------------------------
2. 三次连接握手:
----------------------------------------
对讲机是这样使用的:
C->S: 兄弟,我有重要事情要说,能听到吗?
S->C: 听到了。你能听到我吗?
C->S: 听到了。  
表示连接已经建立了。 下面C -> S 开始说事了。
 
 
准确的说,无穷次确认都无法确认双方建立了可靠连接。但一般只需要3次就可以表示此时连接可用。
 
TCP两端的连接都需要对方的确认。一共两端, 每端都需要发SYN和收ACK, 那这样就是4次,  
而把确认的SYN和ACK一起发显然比较节省带宽, 所以最终形成了三次握手.
TCP连接是一条双向连接,需要client和server都对对方的sequence number进行确认,
因此在client发送SYN后,服务端会对客户端的SYN报文中的sequence number进行确认,
再将自己的sequence number携带给client,等待client端的确认
 
如果是两次连接,就不能形成闭环。 如果第三次丢失,也可以进行通讯。前提是网络是好的。
但是假如网络是好的,就不需要连接的确认。 udp 就是直接发送,接受。非面向连接的。
 
----------------------------------------
3. 四次挥手:
----------------------------------------
C->S: 我的话讲完了,我不说了。
S->C: 好,我知道了.
S->C: 我的话也讲完了。要挂机了。
C->S: 好,挂吧。  
(这些都是tcp协议层 应答信息,不是应用层数据, 所以前面说"我不说了"是不发应用层数据了,
而后面又说"好,挂吧"这是协议层数据不是应用层数据,与不发应用层数据了不矛盾)
 
----------------------------------------
4. 数据通讯。仍然需要数据确认。想一想红蓝对抗。
----------------------------------------
 
----------------------------------------
5. tcp 的状态机
----------------------------------------

客户端
SYN-SENT:发送连接请求sync后等待响应

ESTABLISHED:收到对方响应,并发送一个ack.代表一个连接建立

服务器

LISTEN:侦听来自远方的TCP端口的连接请求
SYN-RECEIVED:响应SYN发送ack,并发送sync后,等待主动方ack的确认
ESTABLISHED:收到ack确认,代表一个连接的建立
 

主动方:
FIN-WAIT-1:发送FIN, 等待ack.
FIN-WAIT-2:收到ack 后,转移到FIN-WAIT-2 状态,等待对方发送FIN信号
TIME-WAIT:收到被动方FIN,发送ack,转移到TIME_WAIT状态,等待足够的时间以确保远程TCP接收到该ack

CLOSED : 在足够长时间后,进入CLOSED 状态,没有任何连接的状态

被动方:
CLOSE-WAIT:收到FIN,给出ack 响应,此时转入CLOSE_WAIT状态,等待从本地用户发来的连接中断请求(close()函数)
LAST-ACK: 用户调用了close函数,被动方发送FIN, 进入LAST_ACK状态,等待主动方连接中断请求的确认
CLOSED:收到确认ack后,进入CLOSED 状态,没有任何连接状态
 
----------------------------------------
6. tcp 的状态迁移
----------------------------------------
这里客户代表主动方,服务器代表被动方。
建立连接状态迁移:
客户: SYN_SEND, ESTABLISHED
服务器: SYN-RECEIVED, ESTABLISHED
 
关闭连接状态迁移:
主动方: FIN-WAIT-1, FIN-WAIT-2, TIME_WAIT, CLOSED
被动方: CLOSE-WAIT,LAST-ACK,CLOSED
 
 
----------------------------------------
7. 其它:
----------------------------------------
time_wait 是合法状态,
主动关闭方发送最后一个ack. 有可能丢失, 此时被动方会重发fin.
如果主动方处于close 状态,就会响应rst 而不是ack.  
所以主动方要处于time_wait 状态,(停留2个MSL 时间,一来一回的时间,所以是2个MSL)。而不是closed
MSL : RFC 建议2分钟, 而实现实际是30秒
 MSL 是Maximum Segment Lifetime, 最长报文段生命周期.

在2个MSL等待时间里没有收到任何被动方的消息(表示整个的关闭流程已经完成),主动方就可以安全转入closed 状态了.


发现有太多的time_wait,是服务器主动关闭连接且等待时间30秒以上所导致。 这里我们假定服务器有很多个连接,它主动关闭了很多连接.
如下解决问题:
vim /etc/sysctl.conf
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_fin_timeout=2   // 让time_wait 只等待2秒 以便快速进入关闭状态,tcp_fin_timeout 我的理解是主动关闭方收到被动关闭方的fin 信号,回应ack而进入time_wait的等待时间.
sysctl -p 生效
 
close_wait: (被动方) 大量出现是不正常的。是没有调用close(fd) 所致。
被动方收到FIN, 由TCP 实现ACK, 而进入CLOSE_WAIT 状态。
但被动方迟迟未调用close(), 就会有大量CLOSE——WAIT 状态出现。
危害: 大量被占用的sockfd 没有被释放
 
========================

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值