在第一章的描述中,连接服务器这个概念讲得非常的模糊,当时的描述是”客户端和服务器两边都建立好套接字后,连接就是在两个套接字间建立一条管道的过程“,在这一小节里,我们将很详细的了解“连接”这个过程是如何发生的。
连接的目的:
1.传递必要的信息(端口号,IP)给协议栈
套接字刚刚创建完成的时候,里面并没有存放任何数据,也不知道通信的对象是谁。浏览器可以根据网址来查询服务器的IP地址,而且根据规则也知道应该使用80号端口,但此时也只有浏览器知道这些信息,协议栈是不知道的,因此,我们需要把服务器的IP地址和端口号等信息告知协议栈。
Linux中的接口是 int connect(套接字描述符,通信信息,通信信息大小 )
一般的我们使用一个结构体来装通信信息,而所谓通信信息的大小就是这个结构体的大小
这里主要是客户端方面的。
2.让通信双方获取对方的通信必要的信息
服务器上也会创建套接字,但服务器上的协议栈和客户端一样,只创建套接字是不知道应该和谁进行通信的。更重要的是,客户端在发起请求时一般是用户指定通信对方的IP,和端口,必要信息还是有的,而服务器完全什么都没有。
于是,我们需要让客户端向服务器告知必要的信息,比如“我想和你开始通信,我的IP地址是xxx.xxx. http://xxx.xxx,端口号是yyyy。”可见,客户端向服务器传达开始通信的请求,告知通信对方必要信息也是连接操作的重要目的。
连接的本质:通信双方交换控制信息
3.创建用于存放信息的内存空间
当执行数据收发操作时,我们还需要一块用来临时存放要收发的数据的内存空间,这块内存空间称为缓冲区,它也是在连接操作的过程中分配的。
解释一下,作者在这里的小标题是”连接是什么意思“,然后讲连接都干了什么工作,我觉得”连接过程中的完成的工作“或者”连接的目的“能更好的的概括这部分讲的内容。
控制信息:
大体上可以分为两类,
第一类:头部中记录的信息
客户端和服务器相互联络时交换的控制信息。这些信息不仅连接时需要,包括数据收发和断开连接操作在内,整个通信过程中都需要,这些内容在TCP协议中进行了定义(固定不变)。
由于这些信息会被添加在客户端与服务器之间传递的网络包的开头,我们有把他们称为头部信息。头部的信息非常重要,理解了头部各字段的含义,就等于理解了整个通信的过程。
第二类:套接字中记录的信息
保存在套接字中,用来控制协议栈操作的信息。
包括:应用程序传递来的信息,从通信对象接收到的信息,收发数据操作的执行状态等信息。
对比第一类信息
相比于第一类客户端和服务器端联络时交换的控制信息,第二类信息是只有自身可见的;
第一类信息中的很多关键信息就来自于第二类信息。
第一类控制信息的内容是由协议确定的,而第二类信息则根据不同协议栈的实现机制不同而难以统一。
这个部分有一个很经典的问题:TCP/IP三次握手
三次握手发生在建立连接的过程中
1.第一次握手:在TCP模块处创建表示连接控制信息的头部,然后发送出去
这一步的目的是为了告诉服务器,客户端的IP,端口号等重要信息,这些信息在包头中含有,所以不用在请求正文中再写一次
客户端建立一个只含有控制信息的包,将包头中的SYN比特设置为1(表示请求连接)
通过TCP头部中的发送方和接收方端口号可以找到要连接的套接字
服务器中间处理过程
IP模块执行网络包发送操作后,网络包就会通过网络到达服务器
服务器上的IP模块会将接收到的数据传递给TCP模块
TCP模块根据TCP头部中的信息找到端口号对应的套接字
将信息写入对应的套接字中,并将状态改为正在连接
2.第二次握手:服务器返回响应消息,
和客户端一样,需要在TCP头部中设置发送方和接收方端口号,IP
将包头中SYN比特设置为1(表示接受连接),如果不接受,那么将RTS比特设置为1
此外,还需要将ACK控制位设为1,表示确认收到请求。因为网络包可能会发生丢失,通信双方需要相互确定网络包是否送达,ACK就是进行这一确认的,对于这个确认的过程,我再详细讲一点,因为一开始我自己理解的时候感觉有些缺失感,此处只说了服务器对客户端的确认,没有说客户端对服务器的确认,读到后面才知道这里面有过滤方面的机制。
首先,客户端给服务器发连接请求,SYN位设置为1,等待响应信息;如果一段时间内,客户端没有收到响应消息,那么认为包丢失了,重新发送;服务器每时每刻都有海量的信息吞吐量,我们需要对包进行一个合理的分类和筛选,比如说客户端等待连接的套接字,对于SYN不为1的包一概不接受。客户端发送了连接请求的套接字只会接收ACK为1的包…..(举个例子,里面细节还很多),只需要明白为了提高效率我哦们需要这种筛选机制就可以了。
综上,ACK,SYN的设置不仅仅有确认功能,还有筛选过滤功能
客户端中间处理过程
网络包会返回到客户端
通过IP模块到达TCP模块
通过TCP头部的信息确认连接服务器的操作是否成功。如果SYN为1则表示连接成功。
向套接字中写入服务器的IP地址、端口号等信息,将状态改为连接完毕
3.第三次握手:
服务器返回响应时将ACK比特设置为1,相应地,客户端也需要将ACK比特设置为1并发回服务器,告诉服务器刚才的响应包已经收到。
如果第三次握手失败了怎么办
server端发送了SYN+ACK报文后就会启动一个定时器,等待client返回的ACK报文。如果第三次握手失败的话client给server返回了ACK报文,server并不能收到这个ACK报文。那么server端就会启动超时重传机制,超过规定时间后重新发送SYN+ACK。
到此,客户端,服务器端连接建立完毕,协议栈的连接操作就结束了,也就是说connect已经执行完毕,控制流程被交回到应用程序。
作者是如何组织文章的:
1.本小节对于文章的组织可以说就是没有什么组织,也可以说根本就不需要什么组织。本文一共三个要点,1.解释连接是什么(交换控制信息),2.补充控制信息的知识 3.连接时的具体操作(三次握手)。这三个要点就完全凑够了篇幅,也把要讲的知识基本说全了。
在文章内容上完全是延续上一节建立套接字,继续讲协议栈要进行的连接操作,在逻辑上是有非常清晰的条理的,可以说由于本章内容间连贯性很强,各个部分间的关系就是很简单的线性交互,所以组织文章,搭建理解框架的成本就很低了。
上一篇
英语词汇 六个表示 “想像” 、“设想” 动词 嘉中 imagine、conceive of、 fancy、visualize、 envisage、 envision 这组词语 ...