如果由应用程序来关闭,便叫作“主动套接字关闭”;否则,套接字的关闭便是被动的。
如主动关闭,应用程序会向对方发出一个F I N 包,套接字的状态则变成F I N _ WA I T _ 1 。
正常情况下,通信对方会回应一个A C K 包,我们的套接字的状态随之变成F I N _ WA I T _ 2 。
如对方也关闭了连接,便会发出一个F I N 包,我们的机器则会响应一个A C K 包,
并将己方套接字的状态置为T I M E _ WA I T 。T I M E _ WA I T 状态也叫作2 M S L
等待状态。其中,M S L 代表“分段最长生存时间”(Maximum Segment Lifetime ),
表示一个数据包在丢弃之前,可在网络上存在多长时间。
一旦应用程序进入T I M E _ WA I T 状态,那么就会一直持续M S L 时间的两倍之久。
这样一来,T C P 就可以在最后一个A C K 丢失的前提下,重新发送它,也就是说,
F I N 会被重新传送出去。M S L 时间两倍之久的等待状态结束之后,套接字便进入C L O S E D
状态。采取主动关闭措施时,只有一方发出一个F I N ,并接收一个A C K 响应。然而,
另一方仍然可以自由地发送数据,直到它也被关闭为止。因此,需要两个路径发挥作用。
在一个路径中(即同步关闭),一台计算机和它的通信对方会同时要求关闭;计算机向对方
送出一个F I N 数据包,并从它那里接收一个F I N 数据包。随后,计算机会发出一个
A C K 数据包,对对方的F I N 包做出响应,并将自己的套接字置为C L O S I N G 状态。
计算机从对方那里接收到最后一个A C K 包之后,它的套接字状态会变成T I M E _ WA I T 。
主动关闭时,另一个路径其实就是同步关闭的变体:套接字从F I N _ WA I T _ 1 状态
直接变成T I M E _ WA I T 。若应用程序发出一个F I N 数据包,但几乎同时便从对方
那里接收到一个F I N - A C K 包,这种情况就会发生。在这种情况下,对方会确认收到
应用程序的F I N 包,并送出自己的F I N 包。对于这个包,应用程序会用一个A C K 包
做出响应。T I M E _ WA I T 状态的主要作用是在T C P 连接处于2 M S L 等待状态的
时候,规定用于建立那个连接的一对套接字不可被拒绝。这对套接字由本地I P 端口以及
远程I P 端口组成。对某些T C P 实施方案来说,它们不允许拒绝处于T I M E _ WA I T
状态下的套接字对中的任何端口号。在微软的方案中,不会存在这个问题。然而,若试图通
过一对已处于T I M E _ WA I T 状态的套接字建立连接,就会失败,并返回W S A E A D D R I N U S E 错误。
要解决这一问题(除了等待使用那个本地端口来脱离T I M E _ WA I T 状态的套接字对),
一个办法是使用套接字选项S O _ R E F U S E A D D R 。
被动关闭情况下,应用程序会从对方那里接收一个F I N 包,并用一个A C K 包做出响应。
此时,应用程序的套接字会变成C L O S E _ WA I T 状态。由于对方已关闭自己的套接字,所
以不能再发送数据了。但应用程序却不同,它能一直发送数据,直到对方的套接字已关闭
为止。要想关闭对方的连接,应用程序需要发出自己的F I N ,令应用程序的套接字状态变
成L A S T _ A C K 。应用程序从对方收到一个A C K 包后,它的套接字就会逆转成C L O S E D 状
态。
以上是小第从书上摘的理论,在windows下想在关闭时通知对方其实很简单:
ShutDown(SD_SEND);
closesocket(Sockethandle)