【Linux】网络编程3

文件描述符的作用

在TCP通信的过程,服务器端会产生两类不同的文件描述符,一个是监听的文件描述符;另一个是用于通信的文件描述符。它们有什么不同呢?

监听的文件描述符:

只有一个,它不负责与客户端的通信,只负责检测客户端的连接请求,检测到有客户端发起连接请求后调用accept函数就可以建立新的连接。

通信的文件描述符:

负责和建立连接的客户端进行通信,如果有N个客户端和服务器建立了新的连接, 通信的文件描述符就有N个,每个客户端和服务器都对应一个通信的文件描述符。

文件描述符对应的内存结构:

  • 一个文件文件描述符对应两块内存, 一块内存是读缓冲区, 一块内存是写缓冲区
  • 读数据: 通过文件描述符将内存中的数据读出, 这块内存称之为读缓冲区
  • 写数据: 通过文件描述符将数据写入到某块内存中, 这块内存称之为写缓冲区

监听的文件描述符:

  • 客户端的连接请求会发送到服务器端监听的文件描述符的读缓冲区中
  • 读缓冲区中有数据, 说明有新的客户端连接
  • 调用accept()函数, 这个函数会检测监听文件描述符的读缓冲区

检测不到数据, 该函数阻塞

如果检测到数据, 解除阻塞, 新的连接建立

通信的文件描述符:

  • 客户端和服务器端都有通信的文件描述符
  • 发送数据:调用函数 write() / send(),数据进入到内核中

数据并没有被发送出去, 而是将数据写入到了通信的文件描述符对应的写缓冲区中

内核检测到通信的文件描述符写缓冲区中有数据, 内核会将数据发送到网络中

  • 接收数据: 调用的函数 read() / recv(), 从内核读数据

数据如何进入到内核程序猿不需要处理, 数据进入到通信的文件描述符的读缓冲区中。

数据进入到内核, 必须使用通信的文件描述符, 将数据从读缓冲区中读出即可

文件描述符的作用是什么?

每一个进程都有一个数据结构task_struct,该结构体里有一个指向「文件描述符数组」的成员指针。该数组里列出这个进程打开的所有文件的文件描述符。数组的下标是文件描述符,是一个整数,而数组的内容是一个指针,指向内核中所有打开的文件的列表,也就是说内核可以通过文件描述符找到对应打开的文件。

然后每个文件都有一个inode,Socket 文件的 inode指向了内核中的Socket 结构,在这个结构体里有两个队列,分别是发送队列和接收队列,这个两个队列里面保存的是一个个struct sk_buff,用链表的组织形式串起来。

sk_buff 可以表示各个层的数据包,在应用层数据包叫 data,在 TCP 层我们称为segment,在IP 层我们叫 packet,在数据链路层称为frame。

你可能会好奇,为什么全部数据包只用一个结构体来描述呢?协议栈采用的是分层结构,上层向下层传递数据时需要增加包头,下层向上层数据时又需要去掉包头,如果每一层都用一个结构体,那在层之间传递数据的时候,就要发生多次拷贝,这将大大降低CPU 效率。

于是,为了在层级之间传递数据时,不发生拷贝,只用 sk_buff 一个结构体来描述所有的网络包,那它是如何做到的呢?是通过调整sk buff 中data 的指针,比如:

· 当接收报文时,从网卡驱动开始,通过协议栈层层往上传送数据报,通过增加skb->data 的值,来逐步剥离协议首部。

这是在发送报文的过程中,data指针的移动过程。

相关推荐
王夏奇11 分钟前
C代码—单元测试中的覆盖率—学习笔记
笔记·学习·单元测试
scdifsn11 分钟前
动手学深度学习10.1. 注意力提示-笔记&练习(PyTorch)
pytorch·笔记·深度学习·注意力机制·注意力提示
StudyHappiness15 分钟前
MongoDB新版本,单节点安装
linux·运维·mongodb·kylin
车载诊断技术16 分钟前
电子电气架构--- 实施基于以太网的安全车载网络
网络·人工智能·安全·架构·汽车·电子电器架构
雷神乐乐18 分钟前
Flume学习
hadoop·学习·flume
向上的车轮23 分钟前
ODOO学习笔记(8):模块化架构的优势
笔记·python·学习·架构
运维佬1 小时前
在 Linux 系统上部署 Apache Solr
linux·apache·solr
编程墨客1 小时前
第03章 文件编程
linux·运维·服务器
命里有定数1 小时前
windows工具 -- 使用rustdesk和云服务器自建远程桌面服务, 手机, PC, Mac, Linux远程桌面 (简洁明了)
linux·运维·服务器·windows·ubuntu·远程工作
cleveryuoyuo1 小时前
进程的程序替换exec*函数和shell实现
linux·服务器