shutdown和closesocket区别

来源:互联网 发布:粤语翻译普通话软件 编辑:程序博客网 时间:2024/05/29 12:17

调用 close()/closesocket()函数意味着完全断开连接,即不能发送数据也不能接收数据,这种“生硬”的方式有时候会显得不太“优雅”。


图1:close()/closesocket()断开连接


上图演示了两台正在进行双向通信的主机。主机A发送完数据后,单方面调用 close()/closesocket() 断开连接,之后主机A、B都不能再接受对方传输的数据。实际上,是完全无法调用与数据收发有关的函数。

一般情况下这不会有问题,但有些特殊时刻,需要只断开一条数据传输通道,而保留另一条。

使用 shutdown() 函数可以达到这个目的,它的原型为:

1.  intshutdown(int sock,int howto);  //Linux
2.  intshutdown(SOCKETs,int howto);  //Windows

sock 为需要断开的套接字,howto为断开方式。

howto 在 Linux下有以下取值:

·        SHUT_RD:断开输入流。套接字无法接收数据(即使输入缓冲区收到数据也被抹去),无法调用输入相关函数。

·        SHUT_WR:断开输出流。套接字无法发送数据,但如果输出缓冲区中还有未传输的数据,则将传递到目标主机。

·        SHUT_RDWR:同时断开 I/O流。相当于分两次调用 shutdown(),其中一次以 SHUT_RD 为参数,另一次以 SHUT_WR 为参数。


howto 在 Windows下有以下取值:

·        SD_RECEIVE:关闭接收操作,也就是断开输入流。

·        SD_SEND:关闭发送操作,也就是断开输出流。

·        SD_BOTH:同时关闭接收和发送操作。


至于什么时候需要调用 shutdown() 函数,下节我们会以文件传输为例进行讲解。

close()/closesocket()和shutdown()的区别

确切地说,close() / closesocket()用来关闭套接字,将套接字描述符(或句柄)从内存清除,之后再也不能使用该套接字,与C语言中的 fclose() 类似。应用程序关闭套接字后,与该套接字相关的连接和缓存也失去了意义,TCP协议会自动触发关闭连接的操作。

shutdown()用来关闭连接,而不是套接字,不管调用多少次shutdown(),套接字依然存在,直到调用 close() / closesocket()
将套接字从内存清除。

调用 close()/closesocket() 关闭套接字时,或调用 shutdown()关闭输出流时,都会向对方发送 FIN 包。FIN 包表示数据传输完毕,计算机收到 FIN 包就知道不会再有数据传送过来了。

默认情况下,close()/closesocket()会立即向网络中发送FIN包,不管输出缓冲区中是否还有数据,而shutdown() 会等输出缓冲区中的数据传输完毕再发送FIN包。也就意味着,调用 close()/closesocket() 将丢失输出缓冲区中的数据,而调用shutdown() 不会。

 

0 0
原创粉丝点击