tcp 半关闭

Shutdown的调用
       在关闭socket的时候,可以有两种方式closesocket和shutdown,这两个函数的区别在什么地方呢?
#include<sys/socket.h>            
#include<winsock.h>              
         intshutdown(int s, inthow)          
int shutdown(SOCKET s,inthow)   
 
how
操作
数字
POSIX
Winsock
0
SHUT_RD
SD_RECEIVE
关闭连接接收方
1
SHUT_WR
SD_SEND
关闭连接的发送方
2
SHUT_RDWR
SD_BOTH
关闭双方
                                        Shutdown参数how值介绍
说明 :
1.       shutdown根本没有关闭socket,任何与socket关联的资源直到调用closesocket才释放。
2.       TCP连接的socket是全双工的,也就是说它可以发送和接收数据,但是一个方向上的数据流动和另一个方向上的数据流动是不相关的,shutdown函数的功能也就是体现在这里,它通过设置how选择关闭哪条数据通道(发送通道和接收通道),如果关闭了发送通道,那么这个socket其实还可以通过接收通道接受数据.
3.       当通过以how=1的方式调用shutdown,就可以保证对方收到一个EOF,而不管其他的进程是否已经打开了套接字,而调用close或closesocket就不能保证,因为直到套接字的引用计数减为0时才会发送FIN消息给对方,也就是说,直到所有的进程都关闭了套接字。
例子说明
  客户端(192.168.1.122):客户端连接上服务器后向服务器发送两条数据(数据发送间隔为2秒),等待两秒后立即调用shutdown关闭发送数据通道或者closesocket,然后客户端在一个while循环中等待接受服务器发送回来的数据.
  服务器(192.168.1.112):接受到客户端发送的数据后,休眠4秒后,把得到的数据发送会客户端
 
1.       shutdown关闭发送数据通道后,通过抓包程序获取的tcp处理过程。
   
                 Shutdown关闭socket时,tcp的状态处理过程.
对上面的处理过程进行分析:
l         前面的三条记录是tcp的三次握手.
l         第四条记录就是客户端第一次向服务器发送数据
l         第五条记录是服务器的确认信息
l         第六条记录就是客户端间隔2秒后第二次向服务器发送数据
l         第七条记录时服务器的确认信息
l         第八条记录是在等待2秒后,调用了shutdown,客户端向服务器发送了FIN标志
l         第九条记录时服务器的确认信息
l         第十条记录是服务器接收到客户端的一条记录后休眠4秒,发回给客户端
l         第十一条记录是客户端的确认
l         第十二条记录是服务器接受到客户端的第二条数据后休眠4秒,发回给客户端
l         第十三条记录是客户端的确认
l         第十四条记录是服务器发送完tcp对列中的数据后,向客户端发送FIN标志
l         第十五条记录时客户端对FIN标志的确认
 
2.       closesocket关闭socket,通过抓包程序获取的tcp处理过程
Closesocket关闭socket时,tcp的状态处理过程
 
 
对上面的处理过程进行分析:
l         前面的三条记录是tcp的三次握手.
l         第四条记录就是客户端第一次向服务器发送数据
l         第五条记录是服务器的确认信息
l         第六条记录就是客户端间隔2秒后第二次向服务器发送数据
l         第七条记录时服务器的确认信息
l         第八条记录是在等待2秒后,调用了shutdown,客户端向服务器发送了FIN标志
l         第九条记录时服务器的确认信息
l         第十条记录是服务器接收到客户端的一条记录后休眠4秒,发回给客户端
l         第十一条记录是由于客户端已经通过closesocket关闭了连接,连接已经不存在,因此客户端向服务器发送了RST标志
总结

       为了保证在连接撤销之前,保证双方都能接收到对等方的所有数据,在调用closesocket之前,先调用shutdown关闭发送数据通道


单工就相当于二极管,数据只能从一端流向另一端。全双工就相当于一个完整的电路,数据可以从A流到B,也可以从B流动会到A,他们甚至还可以同时进行。
在计算机连接的另一端发送FIN包时socket不会自动发送FIN包。它为被标识为不可读但可写的状态。 
把socket标识为可写不可读的状态就意味着它并没有断开,只是认为对方告诉自己将不再发送数据了而已。如果是Socket程序,就需要手动调用方法去关闭这个连接,否则它会一直工作。有些恶意攻击的程序就利用这个机制让没有限制半开连接的服务器打开大量的半开连接,使对方的连接数消耗殆尽。所以很多操作系统都自带了半开连接数的使用限制。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值