当前位置: 首页 > Linux

四次挥手和SocketAPI

时间:2023-04-06 21:36:46 Linux

在《三次握手与Socket API》中,我们详细讲解了三次握手和相关API。三向握手是TCP协议的初级阶段,用于在双方之间建立通信连接。显然,一旦建立连接,就会断开连接。打开连接,那么TCP是如何断开连接的呢?奇怪的四次挥手TCP协议建立连接需要三次信息交换,但断开连接时需要四次信息交换。这四次信息交换形象的叫做四次挥手,那么为什么TCP在断开连接的时候需要奇怪呢?四波而不是三波怎么样?要回答这个问题我们必须对TCP协议有进一步的了解。话多的人和话少的人生活中总有两种人,一种话多,一种话少,话少的人很快就无话可说了,一种话少话多说不完,所以会出现这样的情况:A:今天天气好A:今天的饭好吃A:对对对:B我完了:BA:还没完A:明天周五了A:开心A:blablablaA:我也说完了A说完了,整个聊天过程就算是结束了。TCP通信过程与人聊天有何不同?话多话少的人,当然会有数据多和数据少的客户端和服务器。为什么要挥手四次:半关闭在TCP通信中,一方通过向另一方发送带有FIN标志的消息来表示“我完成了”。当一方收到FIN报文后,就知道对方接下来不会再发送数据,这在TCP协议中称为half-close,半关闭。为什么TCP支持半关闭?为什么一方说完,大家不闭嘴?原来TCP通信和两个人聊天是一样的。你一边听一边说,也就是说,你可以同时发送和接收消息。这就是所谓的全双工通信。在这种沟通方式下,并不意味着对方已经说完了。也结束了,所以直到双方都说完之后,连接才会完全关闭。TCP也是全双工通信。TCP规定通信中的任何一方都可以向对方发送FIN信息(意思是我完了),但这只是意味着一方没有什么可发送的,但这并不影响另一方继续发送数据(对方数据尚未发送)。这就是TCP支持半封闭的原因。半关闭的本质是TCP通信中的一方没有数据可发送。虽然没有数据发送,但是可以继续接收数据。挥手四次的过程前面几节就明白了。简单,假设有一个话少的client和话多的server,会出现如下情况:从图中我们可以看出,虽然client已经发送了FIN报文,但是此时server还有数据要发送,所以服务器忽略客户端发送的FIN,继续发送数据,直到服务器也发送完毕。此时服务器发送FIN表示数据已经发送完毕。客户端收到消息后发送ACK回复。这个时候,TCP连接就真正断开了。.但是,值得注意的是,作为程序员,我们在网络编程中几乎不会遇到上述情况。通常,客户端向服务器发送FIN后,服务器不会继续向客户端发送数据。一般来说,TCP通信的整个过程都是由客户端主导的。客户端主动发起连接,获取到所需信息后断开连接。服务器只是被动地与客户端建立连接。返回给客户的是什么?当客户端不想再聊天时,服务器就不会再继续聊天了。总之,客户端和服务器就像用户和客服。整个过程由用户主导,客服只是被动的。回答问题,当用户没有问题的时候,没有客服会继续跟用户聊天,当然除了客服给用户好评,放心,服务端不需要客户端给个好评:),所以我们通常会看到这样的情况:可能有同学会想,为什么B发送的ACK和FIN不能像三次握手一样合二为一呢?是这样的:如果只有三波手,那么TCP就不能支持半关闭。三波手实际上是在说“如果一方闭嘴,那么我们都闭嘴”,虽然作为程序员我们在网络编程中遇到过。是这样的,但是从TCP协议层面来看,应该是支持半封闭的,即支持通信双方一方话多,另一方话少的情况。现在你应该明白为什么你必须挥手四次而不是简单地挥三下了。四向挥手与关闭和三??向握手相同,四向挥手也有相应的API。这样的API有两个,一个是我们常用的close,一个是shutdown。关闭是最常用的一种。由于close是最常用的,close也用在“一方闭嘴,大家闭嘴”的情况下。当客户端执行关闭函数时,会向服务器发送一个FIN消息,服务器操作系统收到消息后会向服务器进程发送EOF(文件结束)。这个时候服务器不管调用send还是recv都会失败。这时服务端认为客户端关闭了连接,于是调用close函数关闭与客户端的连接。客户端收到FIN报文后,用ACK回复确认,四次挥手的整个过程就完成了。四次挥手和关闭:半关闭客户端和服务器使用关闭完成四次挥手是最常见的过程,即“一方闭嘴,所有人都闭嘴”,我们知道TCP,作为一个全-双工通信协议,需要支持半双工Closed,即一方已经说完,另一方还在说话的场景。这个时候,只能听先说完的那个。作为程序员,我们要知道,几乎没有任何应用场景需要用到TCP提供的半封闭能力。当client调用close的时候,如果server不理会,而是继续向client发送数据,那么此时client是接收不到的。当然,这是客户端调用close函数的目的。而如果客户端说:“我无话可说,所以我想向服务器发送一个FIN,但我还是想听服务器讲一会儿,直到对方讲完”?此时client不能调用close,应该调用socket提供的另外一个API,即shutdown。客户端仍然可以继续向客户端发送任意数量的数据,客户端仍然可以接收数据。直到服务器也发送FIN消息并且客户端回复ACK确认后,连接才真正关闭。现在您应该了解如何使用shutdown来利用TCP的半关闭功能。总结本文是继《三次握手与Socket API》之后的第二篇。它描述了四次挥手的过程以及为什么需要它。之所以四次挥手,是因为TCP协议需要提供一种叫做half-close的能力,但是很少有应用场景需要依赖这种能力。作为程序员,我们需要知道,在大多数情况下,使用close可以完成四次挥手,但是如果需要依赖TCP提供的半关闭能力,则需要使用另外一个API,即shutdown。如果您喜欢本系列文章,欢迎关注我的微信公众号码农的荒岛求生,获取更多内容。计算机内功决定程序员的职业高度