一个TCP需要经过四次挥手才可以关闭连接,能够开启四次挥手的函数有两个:
int close(int sockfd)
int shutdown(int sockfd,int howto)
接下来就分别讲解一下这两个函数。
close()函数
函数原型
#include<unistd.h>
int close(int sockfd)
这个函数主要是对套接字进行关闭,要是成功会返回0,要是出错则会返回-1,实际上,它会对套接字引用计数减一,当套接字引用计数为0时,它会彻底释放套接字。
关闭细节
在输入方向,系统内核会将该套接字设置为不可读,任何读操作都会返回异常。
 在输出方向,系统内核尝试将发送缓冲区的数据发送给对端,并最后向对端发送一个 FIN 报文,接下来如果再对该套接字进行写操作会返回异常。
 如果对端没有检测到套接字已关闭,还继续发送报文,就会收到一个 RST 报文,告诉对端:“Hi, 我已经关闭了,别再给我发数据了。”
shutdown()函数
函数原型
#include<sys/socket.h>
int shutdown(int sockfd,int howto)
对已连接的套接字执行 shutdown 操作,若成功则为 0,若出错则为 -1。
第二个参数howto的选项
| 可能值 | 解释 | 
|---|---|
| SHUT_RD(0) | 关闭输入流 | 
| SHUT_WR(1) | 关闭输出流 | 
| SHUT_RDWR(2) | 关闭输入流和输出流,相当于 SHUT_RD 和 SHUT_WR 操作各一次 | 
close()函数和shutdown()函数同时关闭输出输入流的差异
| 顺序 | close | shutdown | 
|---|---|---|
| 第一点 | 关闭连接,并释放所有连接对应的资源 | 不会释放掉套接字和所有的资源 | 
| 第二点 | 存在引用计数的概念,并不一定导致该套接字不可用 | 直接使得该套接字不可用 | 
| 第三点 | 引用计数导致不一定会发出 FIN 结束报文 | 总是会发出 FIN 结束报文 | 
此文章为11月Day 8学习笔记,内容来源于极客时间《网络编程实战》。