• 英文小册原文地址:​​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()​​不会。

这个函数用的并不常用。

返回值

成功返回​​0​​​,发生异常时返回​​-1​​​,并将 ​​errno​​ 设置为合适的值。

例子

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);

参阅

​​close()​​