网络连接过程 套接字 协议栈 的一些理解1
首先注意区分三个名词:
Socket库-socket组件-套接字(socket)
应用程序调用Socket库的socket组件创建了一个套接字.
套接字是一个抽象的概念,他是内存中的一块空间,这块空间存放了协议栈在通信时要用到的一系列的控制信息.
所以两个节点的连接通信,都可以看做是这些控制信息的计算,交换.
1.创建套接字
应用程序调用Socket库的socket组件,socket组件就委托协议栈创建套接字,协议栈接到委托就在内存中分配一块空间,存放初始化的控制信息,并返回此套接字的描述符
2.连接服务器
应用程序调用Socket库的connect组件,connect组件就委托协议栈将本地的控制信息与远程的控制信息做交换,交换信息后,本地就知道远程的地址(ip)和房间号(port)了,远程也知道本地的地址和房间号了.这样我们就叫建立了连接. tcp的三次握手也就发生在这里了.连接成功后,协议栈会再分配出一块内存空间,用于后面收发数据时作为数据的缓冲区.
TCP的三次握手简述
Step 1: 本地协议栈拿着本地的ip,端口+远程的ip,端口+SYN标识设为1(表示可连接) 去访问远程的协议栈
Step 2: 远程协议栈拿到本地的ip,端口后,会返回响应信息,其中会将ACK标识位设为1(表示收到了消息) 去返回给本地的协议栈
Step 3: 本地协议栈拿到远程响应ACK为1,知道可以通信了,会分配数据缓冲区准备数据收发了,并且再将本地请求ACK设为1,通知远程协议栈,我也收到了消息.远程协议栈得到这个消息后就知道了本地也能收到远程的消息.连接就建立了,远程也就要分配数据缓冲区,准备后面的数据收发了.
3.收发数据
数据到达tcp那里,就会按数据缓冲区大小来切割了,切割后的一块数据称一个数据包,IEEE 802.3标准规定是一个数据包最大长度1460字节(MTU),去掉头尾的协议相关数据,剩下的就是可以放应用数据(注意包含应用层的Http协议数据),应用数据的最大长度就是MSS.下面是收发数据时会涉及的主要点
a. 收发数据时主要体现发送时机的策略.一般有两个主要影响因素,一个是缓冲区大小,一个是时间.如果大于缓冲区大小的数据,当然是把缓冲区装满就可以发送了,但有些小数据装不满缓冲区,那协议栈还是要傻等装满再发送显然会使得通信效率降低.所以这里就涉及怎么处理的策略了.一般时间是动态的,缓冲区大小是固定的,时间动态调整的依据来自于请求的频率.如果发生的请求频次很高,那么可能会在还没装满mtu就发送出去.
b. 重发问题,因为将数据分了很多数据包,网络连接过程中涉及的环境因素很复杂,很容易就会发生丢失数据包的情况,所以丢失后重发的容错机制就很有必要了.所以发送了一个数据包后不会立刻销毁,先存着以防可能发生的重发.一般本地协议栈在将数据分包时会记录开始序号,第一个序号通常是随机的,目的防止被别人猜到了,那就不安全了.然后还有长度.通过开始序号+长度也就知道了下一个包的开始序号.
发送方: 现在我发送的是第xxx字节开始的部分,一共有xxx个字节.
接收方: 到第xxx字节前的数据我都已经收到了.
发送方: 现在我发送的是第xxx**+x**字节开始的部分,一共有xxx个字节.
…
这时迟迟没有等到接收方的成功接收消息,那发送方就会开始重发了
有了TCP的这种重发机制,就使得网络连接中的其他部分不用做相关的容错机制了,大不了丢了让他重发.