连接建立
连接关闭
close函数
定义
close函数可以用于关闭套接字,并中只能TCP连接。
#include<unistd.h>
int close(int sockfd);
- close一个TCP套接字的默认行为是把该套接字标记为已关闭,然后立即返回到调用进程。该套接字不能再由调用进程使用,也就是说它不能再作为read或write等函数的第一个参数。
- 套接字发送缓冲区的数据将尝试被发送到对端,发送完毕后会发送一个FIN;
- 套接字接受缓冲区的内容将被丢弃,但会自动发送ACK。
根据上面的描述,如果要完全关闭一个TCP连接,服务端与客户端都需要调用close,其中一个情形是:

描述符引用计数
- 在多进程服务器中,父子进程共享着套接字,套接字的引用计数为2,父进程调用close函数关闭已连接套接字时,导致相应的描述符计数值减一,只有当引用计数为0时才会引发连接的关闭。
shutdown函数
为什么需要shutdown函数
考虑以下场景:
- 某个回射服务器的客户端从键盘接收到EOF之后会立即调用close函数关闭连接;
- 假设在回射服务器调用close的时刻,仍有一些响应在回来的路上,那么回射服务器将无法接收到这些响应(close函数导致接收缓冲区的数据被丢弃);
此时就需要shutdown函数,来关闭连接的一半,使得客户端不能在发送数据,但仍然能够接收数据:
shutdown函数解析
#include<sys/socket.h>
int shutdown(int sockfd,int howto);//成功则返回0,出错返回-1
howto参数:
SHUT_RD
- 关闭连接的读这一半:进程不能对这样的套接字调用任何读函数;
- 套接字中不再有数据可接收,套接字接收缓冲区中的数据都被丢弃(但是ACK照常发送);
- 注意,SHUT_RD没有发送任何的FIN包
SHUT_WR
- 关闭连接的写这一半:进程不能对这样的套接字调用任何写函数;
- 当前残留在发送缓冲区中的数据将被发送,发送完毕后就发送一个FIN;
- 注意,不管当前的套接字引用计数值是多少,这个FIN包都会被发送;
SHUT_RDWR
- 相当于分别调用一次SHUT_RD和SHUT_WR;
以下是汇总: