天天看点

shutdown()的man手册

  • 英文小册原文地址:​​beej.us/guide/bgnet…​​
  • 作者:Beej
  • 中文翻译地址:​​www.chanmufeng.com/posts/netwo…​​

停止对socket继续传送与接受。

函数原型

#include <sys/socket.h>
    
int shutdown(int s, int how);      

说明

如果我不需要再对 socket 进行​

​send()​

​​了,但是我仍然想要​

​recv()​

​socket 的数据,反之亦然,那我该怎么做呢?

当你使用 ​

​close()​

​​ 关闭 socket descriptor 时,它会将 socket 的传送与接收两端都关闭,并且释放 socket descriptor。若你只想要关闭其中一端,你就可以使用 ​

​shutdown()​

​这个函数。

在这些参数中,​

​s​

​​显然是你想要进行动作的 socket,而要进行什么样的动作,则要由 ​

​how​

​​ 参数指定。可以使用 ​

​SHUT_RD​

​​ 来关闭接收,​

​SHUT_WR​

​​ 以关闭传送,或者 ​

​SHUT_RDWR​

​ 将收送功能都关闭。

  • SHUT_RD

    关闭连接的读功能,socket中不再有数据可以被接受,而且socket接收缓冲区中的先有数据都被丢弃。进程不能再对这样的socket调用任何读函数。

  • SHUT_WR

    关闭连接的写功能。当前留在socket发送缓冲区中的数据将被发送掉,后面跟着TCP的正常连接终止序列。进程不能再对这样的socket调用任何写函数。

  • SHUT_RDWR

    连接的读功能和写功能都被关闭,这等于调用​

    ​shutdown​

    ​两次:第一次调用指定​

    ​SHUT_RD​

    ​,第二次调用指定​

    ​SHUT_WR​

    ​。

​shutdown()​

​​用来关闭连接,而不是socket,不管调用多少次​

​shutdown()​

​​,socket依然存在,因为 ​

​shutdown()​

​​并没有释放 socket descriptor,所以即使 socket 已经整个 shutdown 了,最终仍然得透过 ​

​close()​

​关闭 socket。

默认情况下,​

​close()​

​​会立即向网络中发送​

​FIN​

​​包,不管输出缓冲区中是否还有数据,而​

​shutdown()​

​​会等输出缓冲区中的数据传输完毕再发送​

​FIN​

​​包。也就意味着,调用​

​close()​

​​将丢失输出缓冲区中的数据,而调用 ​

​shutdown()​

​不会。

返回值

例子

int s = socket(PF_INET, SOCK_STREAM, 0);

// ...do some send()s and stuff in here...

// and now that we're done, don't allow any more sends()s:
shutdown(s, SHUT_WR);      

参阅