二、用电信号传输 TCP/IP 数据
二、用电信号传输 TCP/IP 数据
1 创建套接字
1.1 套接字的实体就是通信控制信息
在协议栈内部用一块用于存放控制信息的内存空间,里面记录了控制通信操作的控制信息。包括:通信对象的IP地址、端口号、通信操作的进行状态等。套接字只是一个概念,并不存在实体。
协议栈在执行操作时需要查看这些控制信息。例如,需要查看套接字中的通信对象IP地址和端口号,以便发送数据。
协议栈就是根据套接字中记录的控制信息来工作的。
在 windows 中可以通过 netstat
命令显示套接字内容:
netstat
命令是用于显示套接字内容的命令,-ano 选项表示下面的意思:
a 不仅显示正在通信的套接字,还显示包括尚未开始通信等状态的所有套接字
n 显示IP地址和端口号
o 显示使用该套接字的程序PID
1.2 调用socket时的操作
应用程序调用socket申请创建套接字。协议栈会先为该套接字分配所需的内存空间,然后向其写入初始状态,也就是控制信息。
接下来,就会把该套接字的 描述符
告诉给应用程序。
在该阶段,套接字中并没有存储服务器的 IP 和端口号,服务器也还不知道客户端的 IP 和端口号。等在
连接服务器阶段
才会交换这些控制信息。
2 连接服务器
2.1 连接的意思
连接
实际就是通信双方交换控制信息:
- 浏览器把服务器的 IP 和端口号 告诉给协议栈
- 客户端告诉服务器自己的IP和端口号
- 准备数据收发的一连串操作
在连接操作的过程中,还会分配一块缓冲区,它的作用是:临时存放要收发的数据。
2.2 连接操作的实际过程
3 收发数据
3.1 将 HTTP 请求消息交给协议栈
协议栈并不是一收到数据就马上发送出去,而是把放到缓冲区等待,这样做的目的是为了避免大量的小包,导致网络效率下降。对于什么时候才发送,有以下几个判断因素:
-
每个网络包的数据长度。
MTU:一个网络包的数据长度,以太网中一般是1500字节。
MSS:除去头部之后,一个网络包所能容纳的 TCP 数据的最大长度。
-
时间。
3.2 对较大的数据进行拆分
如果发送缓冲区中的内容拆过了 MSS 的长度,TCP模块 就会进行拆分,并在每一块的前面加上 TCP 头部,然后交给 IP模块 来执行数据的发送操作。
TCP 采用序号和ACK的方法来确定对方是否收到了数据,在得到对方确定之前,发送过的数据都会保存在缓冲区中。如果没有收到对方返回的 ACK号,那么就会重新发送这些包。
归功于 TCP 的这一机制,网卡、集线器、路由器都没有错误补偿机制,一旦检测到错误就直接丢弃相应的包。
3.3 根据网路包平均往返时间调整 ACK 号等待时间
当网络传输拥堵时,ACK号的返回就会变慢,这时应该把等待时间设置的长些,否则就会有大量的包重传,导致网络更加拥堵。但是如果设置的时间很长,包的重传就会出现很大的延迟,也会导致网络速度变慢。
TCP 采用了动态调整等待时间的方法,这个时间是根据ACK号返回所需的时间来判断的。
3.4 使用窗口有效管理 ACK 号
滑动窗口方法
造成的问题是:发送包的频率会超过接收方的处理能力。
解决办法:接收方告诉发送方自己最多能够接受多少数据,然后发送方根据这个值进行控制。
3.5 接收 HTTP 响应消息
浏览器在委托协议栈发送请求消息之后,会调用 read 程序来获取响应消息。如果响应消息还没有返回,这时接收缓冲区中没有数据,协议栈就会将应用程序挂起,等响应消息到达之后再执行接收操作。
协议栈接受数据:检查是否有数据丢失,并返回ACK;将数据块放到接受缓冲区,并拼接,最后把数据交给应用程序(将接受到的数据复制到应用程序指定的内存地址)。
4 从服务器断开并删除套接字
4.1 数据发送完毕后断开连接
在 HTTP1.0 中,web服务器返回响应消息后,服务器就会发起断开过程。
在 HTTP1.1 中,服务器返回响应消息后,客户端仍然可以发起下一次请求消息,如果接下来没有请求要发送,客户端就会发起断开过程。
4.2删除套接字
通信结束后,并不是立即就删除该套接字,而是会等待一段时间之后再删除。原因:防治误操作。
例如:
- 客户端先发起FIN
- 服务器返回ACK
- 服务器发起FIN
- 客户端返回ACK
如果在第4步中网络包丢失了,这时服务器就会重发一次 FIN。如果这时在客户端中该套接字已经被删除,并且已经分配给另一个应用程序使用,这时这个FIN就会跑到这个新的套接字里,新的套接字就会执行断开过程。发生了误操作。
5 IP与以太网的包收发操作
5.1 包收发操作
路由器
根据目的IP地址得到下一个路由器的位置,是按照 IP 规则
传输包。
集线器
将包传输给下一个路由器,是按照 以太网规则
传输包。
IP和以太网规则就像:IP规则计算出位置,然后把位置告诉以太网规则,让它去干活。
这样分开的好处是:可以更好地根据需要使用各种通信技术。
5.2 生成 IP 头部
IP模块在生成 IP 头部时,最重要的内容就是 IP 地址,包括发送方的 IP 地址和接收方的 IP 地址,其中接收方的 IP 地址是由 TCP模块告诉的,而TCP又是在连接阶段从应用程序那里获得的。
关于发送方的 IP 地址,如果计算机上有多块网卡,IP模块就需要通过 “路由表” 来得到应该把包发送给哪个网卡。
IP地址实际上是分配给网卡的,因此如果计算机上有多块网卡,每一块网卡都会有自己的IP地址。
5.3 生成 MAC 头部
MAC 头部中的字段包括:
- 接收方的 MAC 地址
- 发送方的 MAC 地址
- 以太网类型:IP协议、ARP协议等