tcp 协议通俗解释。

来源:互联网 发布:python源码剖析 epub 编辑:程序博客网 时间:2024/04/28 19:08
----------------------------------------
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 的状态机
----------------------------------------
LISTEN:侦听来自远方的TCP端口的连接请求
SYN-SENT:发送连接请求后等待响应
SYN-RECEIVED:响应SYN-SEND发送ack后,等待主动方ack的确认
ESTABLISHED:代表一个打开的连接
 
FIN-WAIT-1:发送FIN, 等待ack.
FIN-WAIT-2:收到ack 后,转移到FIN-WAIT-2 状态
TIME-WAIT:收到被动方FIN,发送ack,等待足够的时间以确保远程TCP接收到该ack
 
CLOSE-WAIT:响应匹配FIN-WAIT-1,等待从本地用户发来的连接中断请求(close()函数)
LAST-ACK: 被动方发送FIN, 等待主动方连接中断请求的确认
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 时间)。而不是closed
MSL : RFC 建议2分钟, 而实现实际是30秒
 
发现有太多的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
sysctl -p 生效
 
close_wait: (被动方) 大量出现是不正常的。是没有调用close(fd) 所致。
被动方收到FIN, 由TCP 实现ACK, 而进入CLOSE_WAIT 状态。
但被动方迟迟未调用close(), 就会有大量CLOSE——WAIT 状态出现。
危害: 大量被占用的sockfd 没有被释放
 
========================
1 0
原创粉丝点击