TCP之半打开和半关闭

    TCP是一个全双工(Full-Duplex)协议,因此标题里的"半"字就是相对于全双工的"全"来说的。

半开连接

    从协议定义的角度来说,TCP的半开连接是指:TCP连接的一端异常崩溃,或者在未通知对端的情况下关闭连接,这种情况下不可以正常收发数据,否则会产生RST。比如一个常见的情况是TCP连接的一端异常断电,就会导致TCP的半开连接。如果没有数据传输,对端就不会知道本端的异常而一直处于ESTABLISHED状态(暂不考虑TCP存活检测机制)。

    另外从linux实现的角度来说,因为linux内部有个半连接队列,TCP半开连接是指发送了TCP连接请求,等待对方应答的状态。此时连接并没有完全建立起来,双方还无法进行通信交互的状态,此时就称为半连接。由于一个完整的TCP连接需要经过三次握手才能完成,这里把三次握手之前的连接都称之为半连接。

    通过单台笔记本的双无线网卡测试tcp连接的半开,步骤如下:

1. server绑定网卡A的地址(172.168.18.240)

2. client绑定网卡B的地址(172.168.52.224)并连接server,对应截图中的No1~No3包

3. client发送"hello"消息,对应截图中的No4包

4. server正常接收到后"hello"消息后,拔掉网卡A 

5. kill掉server进程,使server的FIN消息不能发送到client

6. 插上网卡A,注意在路由器中绑定IP地址和MAC地址,使得网卡A的地址和之前是一致的,此时client和server即处于半开连接状态

7. client向server发送"world"消息,对应截图中的No6包

8. server回复rst消息

半关连接

    TCP的半关连接是指:TCP连接只有一方发送了FIN,另一方没有发出FIN包,仍然可以在一个方向上正常发送数据。这种场景并不常见,一般来说Berkeley sockets API调用shutdown()接口时候就会进入半关闭状态(调用常规的close()一般是期待完整的双向关闭这个TCP连接),shutdown()接口相当指示程序,本端已经没有数据待发送,所以我发送一个FIN到对端,但是我仍然想要从对端接收数据,直到对端发送一个FIN指示关闭连接为止。如下图所示,在红色背景文本框标注的数据传输场景下就是TCP的半关连接。

    测试过程:

1. 正常建立连接后,client首先发送"hello"消息给server,对应截图中的No1~No5包

2. 然后server发送FIN给client,关闭了server到client方向的数据传输,对应截图中的No6~No7包

3. 但是client仍然可以向server传输数据,此时client和server之间的连接即处于半关连接的状态,接下来client向server发送"world"消息,对应截图中的No8~No9包

4. 然后发送FIN给server关闭client到server方向的数据传输,对应截图中的No9~No10包。

扩展:半连接

    发生在TCP3次握手中。如果客户端向服务端发起TCP请求,服务端也按照正常情况进行响应了,但是客户端不进行第3次握手,这就是半连接。半连接,会造成服务端分配的内存资源就一直这么耗着,直到资源耗尽(也就是常听说的SYN洪水攻击的原理)。

参考文章:

http://www.cnblogs.com/lshs/p/6038472.html

 

转载于:https://my.oschina.net/vbird/blog/1528209

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值