它们分别代表了文件系统操作的抽象层和跨网络通信的接口
理解并熟练运用这两者,是掌握Linux系统编程的关键
本文将从VFS的基本概念出发,逐步深入到Socket编程的基础,旨在为读者提供一个全面而深入的视角
VFS:Linux的核心抽象层 VFS,即虚拟文件系统,是Linux内核中的一个非常核心的概念
它作为文件系统操作的抽象层,为应用程序员提供了一层屏蔽底层文件系统差异的抽象
不同的文件系统,如Ext2/3、XFS、FAT32等,具有不同的结构,而用户调用如`open`等文件I/O函数时,如果直接面对这些底层差异,将极大地增加编程的复杂性
因此,Linux引入了VFS的概念,相当于是Linux自建了一个新的贮存在内存中的文件系统,所有其他文件系统都需要先转换成VFS的结构才能为用户所调用
VFS的构建与结构 VFS的构建过程,实质上是加载实际文件系统的过程,也就是`mount`命令被调用的过程
以挂载一个Ext2文件系统为例,`mount`命令的一般形式为`mount /dev/sdb1 /mnt/mysdb1`,其中`/dev/sdb1`是设备名,`/mnt/mysdb1`是挂载点
VFS文件系统的基本结构由`dentry`结构体与`inode`结构体组成
`dentry`代表一个文件目录中的一个点,可以是目录也可以是文件
而`inode`则代表一个在磁盘上的文件,它与磁盘文件一一对应
需要注意的是,`inode`与`dentry`不一定一一对应,一个`inode`可能会对应多个`dentry`项
在挂载文件系统时,Linux首先找到磁盘分区的super block,然后通过解析磁盘的`inodetable`与`file data`,构建出自己的`dentry`列表与`inode`列表
这一过程对于Ext2/3等Linux原生文件系统而言相对简单,但对于其他文件系统则可能会慢得多
VFS的dentry cache与文件定位 为了避免资源浪费,VFS采用了`dentry cache`的设计
当有用户用`ls`命令查看某一个目录或用`open`命令打开一个文件时,VFS会为这里用的每个目录项与文件建立`dentry`项与`inode`,即“按需创建”
然后维护一个LRU(Least Recently Used)列表,当Linux认为VFS占用太多资源时,VFS会释放掉长时间没有被使用的`dentry`项与`inode`项
由于`dentry cache`的存在,文件的定位方式也分为两种:有`dentry`时定位与无`dentry`时定位
在有`dentry`时,可以通过`dentry`中的`d_subdirs`快速定位到目标文件;而在无`dentry`时,则需要通过遍历`inode`列表和解析目录文件数据来重建`dentry`和`inode`
Socket:网络通信的桥梁 在Linux系统编程中,Socket是网络编程的基础
它提供了跨网络通信的接口,使得不同主机上的应用程序能够进行通信
互联网通过TCP/IP协议完成通信,而Socket把TCP/IP复杂的协议族集成为相关函数,通过调用Socket相关函数就可以完成网络通信
Socket的分类与工作原理 Socket分为流Socket和数据报Socket
流Socket提供了一个可靠的双向的字节流通信信道,即保证发送者传输的数据会完整地到达接收程序,它使用了传输控制协议(TCP)
数据报Socket允许数据以消息的形式进行交换,但数据传输是不可靠的,消息的到达可能是无序的、重复的或根本无法到达,它使用了用户数据报协议(UDP)
流Socket通常分为主动Socket和被动Socket,被动Socket通常也叫服务器,主动Socket通常叫客户端
Socket编程的基本流程如下: 1.服务器端: