Skip to content

4 协议栈, 网卡, 网线

协议栈

协议栈:网络控制软件 网卡:网络硬件

协议栈的内部结构: ![[Excalidraw/计算机/四大件/计算机网络 Draw.md#^group=mSlDrTNw]] ICMP 协议:用于告知网络包传送过程中产生的错误以及各种控制信息 ARP 协议:用于根据 IP 地址查询相应的 以太网 MAC 地址

使用 TCP 协议传输

创建套接字

  • 准备创建套接字【套接字就是存放控制信息(IP 地址,端口号,通信状态)的内存空间的抽象概念】
  • 协议栈向操作系统申请内存空间来放置套接字,并将套接字设为初始状态
  • 套接字创建成功之后,协议栈会返回一个描述符给应用程序,用于唯一标识套接字

连接 Web 服务器

  • 服务器程序一般会在系统启动时就创建套接字,等待服务端进行连接
  • 之后 TCP 模块会把包含控制信息的 以太网头部TCP 头部 的网络包委托给 IP 模块 进行发送
  • 等到服务器端的 IP 模块 接收到信息后,就把信息传递给服务器端的 TCP 模块,服务器根据这些信息就知道自己要使用哪个套接字,也知道了客户端的信息。
  • 服务端会修改套接字的状态
  • 服务端向客户端发送信息,告诉客户端已收到,可以进行连接
  • 客户端收到信息后,会再次给服务端发信息说,我收到了
  • 至此,连接完成

[!question] 为什么最后还要多此一举向服务器端发送消息? 最后一次是客户端向服务器端发送网络包的随机序列号,我们不能真的从 1 开始傻傻的排序,因为这样通信过程很容易被预测,容易被攻击,所以起始序列号必须随机

收发数据

指定 描述符需要发送的数据,协议栈通过 套接字【连接成功后,套接字中会有通信对方的信息,所以发送数据无需指明_IP 地址端口号_】把数据发送给 Web 服务器

![[Excalidraw/计算机/四大件/计算机网络 Draw.md#^group=No6ib08t|600]] 发送时,发送方会说“现在发送的是从 xx 字节开始的部分,一共有 xx 字节” 接收方则回复说“到 xx 字节之前的数据我已经收到了” ![[Excalidraw/计算机/四大件/计算机网络 Draw.md#^group=H9yqiQ8G|530]]

断开连接

![[Excalidraw/计算机/四大件/计算机网络 Draw.md#^group=UZ67GJjD|520]]

删除套接字

为了 防止误操作,删除套接字要过一段时间

在断开连接时,服务器最后发送给客户端的ACK号丢失了,那么客户端会再次发送一个 FIN:1的包。
如果这时服务器端的套接字已经删除了,更巧的是,某个在服务器端的另一个程序重新创建的套接字的端口号与刚刚被删除的套接字的端口号一样,那。。。接下来的通信就是“牛头不对马嘴”

经过协议栈之后,我们就已经得到了带有各种控制信息的包,接下来我们把包交给网卡进行传输

网卡

mermaid
graph LR
	a(协议栈)--带有0和1的数字信号的网络包-->b(网卡)--电信号/光信号-->c(网线/光纤)
	c-->d(路由器,集线器等转发设备)
	d-->e(接收方)

网卡将包转换成电信号通过网线发送出去

网卡驱动从 IP 模块获取包之后,会将其复制到网卡内的缓冲区中; 接下来 MAC 模块会将包从缓冲区中取出,并在开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列; 之后网卡的 MAC 模块生成电信号【通用信号】,然后由 PHY(MAU) 模块转换成可在网线中传输的格式,并通过网线发送出去 ![[Excalidraw/计算机/四大件/计算机网络 Draw.md#^group=ZpB4IHEP|500]]

网线

传输电信号

[!question] 怎么解决传输时电信号的衰减? ![[Excalidraw/计算机/四大件/计算机网络 Draw.md#^group=8iOnlDvg|500]] 使用双绞线【将两根信号线缠绕在一起形成一组】 ![[Excalidraw/计算机/四大件/计算机网络 Draw.md#^group=pZqxXexl|600]]