https://www.cnblogs.com/zyp221314/p/9228701.html
https://blog.csdn.net/xiaofei0859/article/details/6050806
https://blog.csdn.net/pearl_c/article/details/51226320
https://blog.csdn.net/zhangxiao93/article/details/52078784
https://blog.csdn.net/u010821666/article/details/81841755
https://blog.csdn.net/wj2555111/article/details/105387405
shutdown可以实现优雅关闭,close关闭直接清空读缓冲区,并且,在读缓冲区有数据时,会给对方发送rst
在阻塞情况下,close之后,发送缓冲区的数据会继续由操作系统接管进行发送。但是为非阻塞套接字的时候,发送缓冲区的数据会直接清除掉。
SO_LINGER
https://www.cnblogs.com/my_life/articles/5174585.html
close与shoudown都是告诉对方不要给我发送数据,但是对方发送缓冲区里面的数据依然可以发送给我,这个时候使用showdow关闭写端后我依然可以读缓冲区里面的数据,但是close不可以。在我发送fin以后,对方依然调用write给我写数据时,如果对方写缓冲区可以正常使用则可以继续发送过来,但是主动关闭的一方会返回rst,对方如果此时继续发送数据,那么对方的操作系统会给进程返回sigpipe,使得进程退出。
对于Linux下来说,无论是FIN还是RST,应用层read将会返回0,可以认为对方请求关闭链接,调用close关闭fd即可。

rst报文
1.提前关闭
关于 TCP ,我想我们在教科书里都读到过一句话, 'TCP 是一种可靠的连接 ' 。 而这可靠有这样一种含义,那就是操作系统接收到的来自 TCP 连接中的每一个字节,我都会让应用程序接收到。如果应用程序不接收怎么办?你猜对了, RST 。就是说,如果tcp接受缓冲区里面有数据,但是你没有处理,直接调用了close,那么这个时候会给对方发送rst。
2.在一个已关闭的 socket 上收到数 据
如果某个 socket 已经关闭,但依然收到数据也会产生 RST 。对一个调用了close或者shutdown写端的套接字写数据,那么会使得对方返回rst。
3.请求端口不存在
4。请求超时
曾经遇到过这样一个情况 : 一个客户端连接服务器, connect 返回 -1 并且 error=EINPROGRESS 。 直接 telnet 发现网络连接没有问题。 ping 没有出现丢包。用抓包工具查看,客户端是在收到服务器发出的 SYN 之后就莫名其妙的发送了 RST 。
比如像下面这样 :
图片说明
有 89 、 27 两台主机。主机 89 向主机 27 发送了一个 SYN ,表示希望连接 8888 端口,主机 27 回应了主机 89 一个 SYN 表示可以连接。但是主机 27 却很不友好,莫名其妙的发送了一个 RST 表示我不想连接你了 。
后来经过排查发现,在主机 89 上的程序在建立了 socket 之后,用 setsockopt 的 SO_RCVTIMEO 选项设置了 recv 的超时时间为100ms 。而我们看上面的抓包结果表示,从主机 89 发出 SYN 到接收 SYN 的时间多达 110ms 。(从 15:01:27.799961 到15:01:27.961886 , 小数点之后的单位是微秒)。因此主机 89 上的程序认为接收超时,所以发送了 RST 拒绝进一步发送数据 。
图片说明
崩溃对端会关闭所有套接字,并向对方发送fin,之后再也不会发送任何数据,对方不知道这一端已经崩溃,向这一端继续写数据时,会返回rst。
5.TCP收到了一个根本不存在的连接上的分节
6.处理半打开连接, 一方关闭了连接,另一方却没有收到结束报文(如网络故障),此时另一方还维持着原来的连接。而一方即使重启,也没有该连接的任何信息。这种状态 就叫做半打开连接。而此时另一方往处于半打开状态的连接写数据,则对方回应RST复位报文
图片说明
https://blog.csdn.net/wj2555111/article/details/105387405