嵌入式Linux——文件类型
目录
普通文件
目录文件
目录文件的权限与管理
字符设备文件和块设备文件
符号链接文件
查看符号链接
删除符号链接
修改符号链接
管道文件
匿名管道(Anonymous Pipe)
匿名管道的特点:
使用示例:
命名管道(Named Pipe)
命名管道的特点:
使用示例:
套接字文件
套接字的基本概念
Unix 域套接字(Unix Domain Socket)
特点:
创建和使用 Unix 域套接字
示例代码:
网络套接字(Network Socket)
特点:
创建和使用网络套接字
示例代码:
Linux 下一切皆文件,文件作为Linux 系统设计思想的核心理念,在Linux 系统下显得尤为重要。 在 Windows 系统下,操作系统识别文件类型一般是通过文件名后缀来判断,譬如 C 语言头文件.h、C语言源文件.c、.txt 文本文件、压缩包文件.zip 等,在 Windows 操作系统下打开文件,首先会识别文件名后缀得到该文件的类型,然后再使用相应的调用相应的程序去打开它;譬如.c 文件,则会使用 C 代码编辑器去打开它;.zip 文件,则会使用解压软件去打开它。
但是在Linux 系统下,并不会通过文件后缀名来识别一个文件的类型,话虽如此,但并不是意味着大家可以随便给文件加后缀;文件名也好、后缀也好都是给“人”看的,虽然Linux 系统并不会通过后缀来识别文件,但是文件后缀也要规范、需要根据文件本身的功能属性来添加,譬如 C 源文件就以.c 为后缀、C 头文件就以.h 为后缀、shell 脚本文件就以.sh 为后缀、这是为了我们自己方便查看、浏览。
普通文件
普通文件就是分为文本文件和二进制文件:
文本文件就是由ASCII文本字符构成的,虽说本真上还是0和1组成,但是他们排列得到的时人类可读的文本文件。
二进制文件是正儿八经的0和1,他们是计算机用来识别处理的文件。
关于文件,可以使用stat来查看一个文件的文件类型:
[root@VM-12-17-centos learn_linux]# stat open.txtFile: ‘open.txt’Size: 0 Blocks: 0 IO Block: 4096 regular empty file Device: fd01h/64769d Inode: 528367 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2024-11-20 19:17:48.998832078 +0800 Modify: 2024-11-20 19:17:48.752830223 +0800 Change: 2024-11-20 19:17:48.752830223 +0800Birth: -
这是笔者尝试的,你也可以试试看
目录文件
目录文件(Directory File)是文件系统中用于组织和管理其他文件的特殊类型文件。它本质上是一个包含指向其他文件或子目录的条目的文件。目录文件的作用类似于文件夹,用于存储文件路径信息,帮助操作系统快速定位文件的存储位置。目录文件并不直接存储数据,而是存储文件名和文件元数据(如文件位置、权限、大小等)的映射。
在 Linux 文件系统中,目录文件通常被视为一个特殊的文件,它是文件系统结构的基本组成部分之一。每个目录都可以包含若干个文件或子目录,操作系统通过目录文件来构建文件系统的层级结构。通过目录文件,用户和程序可以方便地对文件进行管理、存取和操作。
一个目录文件通常包含一个列表,其中每一项表示一个文件或子目录。每一项包含以下信息:
-
文件名:文件或子目录的名称。
-
文件的元数据:例如文件的 inode(索引节点)编号,用于标识文件在磁盘上的位置及其他信息(如权限、大小等)。
在传统的 UNIX 文件系统中,目录文件的结构可以简单地理解为一个包含若干条目(文件名与 inode 映射)的数组。每个条目记录一个文件或子目录的名称及其对应的 inode。
对于目录文件,操作系统通常提供一系列操作,包括:
-
创建目录:通过
mkdir
命令,操作系统会在指定位置创建一个新的目录文件。该目录文件本身不包含数据,而是为空目录,等待被填充文件或子目录。 -
删除目录:通过
rmdir
命令,操作系统可以删除空目录。如果目录不为空,则需要先删除其中的文件或子目录,或者使用rm -r
命令递归删除。 -
打开和关闭目录:在程序中,目录文件可以像普通文件一样被打开和关闭。通过
opendir()
和closedir()
函数,程序可以打开和关闭目录,获取目录中的文件列表。 -
读取目录内容:可以使用
readdir()
函数读取目录中的每一项。这些项通常包含文件名和文件对应的 inode 编号,通过 inode 可以访问文件的更多信息。
目录文件的具体实现依赖于文件系统的类型,不同的文件系统采用不同的方式来存储和管理目录内容。在大多数现代文件系统(如 ext4、NTFS)中,目录文件通常是一个特殊的文件类型,内部存储的是一个结构化的条目列表,每个条目指向一个文件的 inode 或子目录。
以 ext4 文件系统为例,目录文件由多个目录项(directory entry)组成,每个目录项包括文件名、文件的 inode 号和其他元数据。目录项按顺序排列,操作系统通过遍历这些目录项来查找文件或子目录。
每个文件在文件系统中都有一个与之关联的 inode(索引节点),它包含文件的元数据(如权限、大小、创建时间等),以及文件的数据块位置。然而,目录文件本身并不直接包含文件的数据,而是通过 inode 来引用其他文件或子目录。目录文件实际上是 inode 的一个映射表,操作系统通过 inode 查找文件的存储位置及其他信息。
目录文件与 inode 的关系可以通过一个简单的例子来理解:当用户通过命令行或图形界面创建一个新文件时,操作系统首先会为该文件分配一个 inode,并将该 inode 的编号以及文件名存储在父目录的目录文件中。此后,操作系统通过该目录文件与 inode 之间的映射关系来访问文件的实际数据。
目录文件提供了文件系统的层次结构,用户通过目录文件可以对文件进行分类管理。目录文件通常用于:
-
组织文件:文件系统通过层级结构组织文件,每个目录都可以包含多个子文件和子目录。通过这种方式,文件系统可以有效地管理大量的文件,并方便用户进行文件分类和访问。
-
查找文件:操作系统可以根据目录文件的条目快速定位到文件的 inode,从而访问文件的实际数据。这种结构大大提高了文件查找的效率,尤其是在包含大量文件的大型文件系统中。
-
支持路径解析:目录文件支持路径解析功能,例如
/home/user/Documents/file.txt
,每个目录文件表示路径中的一部分,操作系统通过解析路径中的各个目录,最终定位到文件。
目录文件的权限与管理
与普通文件一样,目录文件也有权限控制,决定了哪些用户可以访问、修改或删除目录。目录文件的权限通常包括:
-
读取权限(r):允许用户列出目录中的文件。
-
写入权限(w):允许用户向目录中添加、删除或重命名文件。
-
执行权限(x):允许用户进入目录进行操作。
如果目录没有执行权限,用户将无法访问该目录中的文件,尽管用户可能具有读取或写入权限。同样,目录的所有者或管理员可以修改目录文件的权限,以控制哪些用户可以访问或修改目录。
字符设备文件和块设备文件
字符设备文件和块设备文件是 Linux 操作系统中两种基本的设备文件类型。设备文件是指操作系统中用于表示外部设备的特殊文件,它们与普通文件有本质的区别,主要用于与硬件设备进行交互。字符设备文件和块设备文件分别处理不同类型的设备交互,理解它们的区别与特点对于掌握 Linux 系统的底层操作至关重要。
字符设备文件是用于表示字符设备的特殊文件。字符设备是指那些一次只能处理一个字符流的设备,数据的读写是按字符为单位进行的。字符设备文件提供了一种简单的接口,通过它可以与字符设备进行数据交换。常见的字符设备包括串口设备、键盘、鼠标、打印机等。
在 Linux 系统中,字符设备文件通常位于 /dev
目录下,文件的命名方式一般是设备的名称或标识符,如 /dev/ttyS0
(表示串口设备),/dev/console
(表示控制台设备)。这些设备文件是通过设备驱动程序与内核直接进行交互的,内核通过驱动程序将用户程序发出的字符流数据传递给硬件设备,或者将硬件设备返回的数据传递给用户程序。
字符设备文件的核心特性之一是它们采用的是“字符流”的方式进行数据传输,数据的读取和写入是顺序进行的,没有固定的“块”结构。对于字符设备,内核通常提供了基本的读、写、打开和关闭等操作。字符设备的驱动程序会处理这些操作并实现对设备的具体控制。
在操作系统内部,字符设备文件与应用程序之间的交互是通过系统调用实现的。比如,应用程序可以通过 read()
和 write()
系统调用来与字符设备进行数据传输。这些系统调用会触发内核中字符设备驱动程序的相应操作,从而实现与硬件的交互。
字符设备的驱动程序通常需要实现一些基本的操作函数,如打开设备、关闭设备、读数据、写数据等。这些操作函数通常会被注册到 Linux 内核的设备模型中,使得内核能够在用户程序发出请求时,自动调用相应的驱动程序函数。
块设备文件是用于表示块设备的特殊文件。块设备是指那些一次可以读取或写入一个固定大小数据块的设备,数据的传输通常是按块(block)为单位进行的。与字符设备相比,块设备能够更高效地处理大量数据,且数据传输是按固定的块结构进行的,通常可以随机访问。常见的块设备包括硬盘、固态硬盘(SSD)、CD-ROM 驱动器等。
在 Linux 系统中,块设备文件通常也位于 /dev
目录下,文件的命名方式一般是设备的名称或标识符,如 /dev/sda
(表示第一个硬盘),/dev/sdb
(表示第二个硬盘)。与字符设备文件不同,块设备文件代表的设备支持更复杂的操作,包括分区、格式化、挂载等。
块设备文件的特性之一是它们采用的是“块”结构的数据传输方式。每个块的大小通常是 512 字节或 4 KB,这取决于具体的硬件设备。在块设备的操作过程中,数据按块的粒度进行读取和写入,内核和硬件之间的交互通常是批量处理的,而不是逐字符传输。这使得块设备在处理大容量数据时效率更高,特别是在存储设备如硬盘、固态硬盘等中,块设备可以更快速地进行顺序和随机访问。
块设备的驱动程序通常需要处理对设备的读写请求。每当用户程序请求读取数据时,内核会将请求转发给块设备的驱动程序,驱动程序根据请求的块号读取相应的数据并将其返回给应用程序。类似地,写操作也会将数据写入指定的块。块设备驱动程序还可能需要处理数据的缓存、同步、磁盘调度等问题。
字符设备和块设备的区别主要体现在数据传输方式、访问粒度、设备类型和性能等方面。
-
数据传输方式:字符设备按字符流传输数据,一次只处理一个字符或字节;块设备按块(block)传输数据,通常一次处理较大的数据块(通常是 512 字节或 4 KB),支持更高效的顺序和随机访问。
-
访问粒度:字符设备的访问粒度较小,通常为一个字符或字节;块设备的访问粒度较大,通常为一个数据块,适合大规模数据的读写。
-
设备类型:字符设备适用于那些数据流量较小且不需要高效随机访问的设备,如键盘、鼠标、串口等;块设备则通常用于存储设备,适合大容量数据的存储与管理,如硬盘、固态硬盘等。
-
性能:由于块设备采用块结构传输数据,能够在访问大数据时提供更高的性能,尤其是在顺序访问模式下。字符设备则更适合流式传输,性能相对较低。
-
驱动程序:字符设备的驱动程序通常实现的是基于字符流的操作,功能较为简单,主要处理设备的读写操作;而块设备的驱动程序则需要处理更多复杂的操作,如磁盘调度、缓存管理、分区管理等。
字符设备主要适用于需要逐字符或逐字节交互的场合。例如,键盘、鼠标、串口设备等,用户通过这些设备与计算机进行交互,通常涉及较小的数据量和流式数据传输。字符设备的接口简单,驱动程序也相对简单,因此适用于那些数据传输要求不高的设备。
块设备则更适合存储设备,如硬盘、固态硬盘、光盘等。这些设备通常需要处理大量数据,并且数据的读写操作是按块进行的。块设备能够提供较高的性能,尤其是在需要进行顺序读写的场景下,如大规模文件存储、数据库操作等。块设备的管理复杂性较高,通常需要实现更为复杂的调度算法和缓存策略,但在处理大数据时具有显著的优势。
符号链接文件
符号链接文件(Symbolic Link,简称 symlink),也叫软链接,是一种特殊的文件类型,它包含指向其他文件或目录的路径。与硬链接不同,符号链接并不直接指向文件的 inode,而是存储一个文本字符串,这个字符串是另一个文件或目录的路径。符号链接为用户和程序提供了一种间接访问文件的方式,允许通过一个链接访问目标文件或目录。
符号链接的最重要特性是它可以跨越文件系统的边界,允许一个文件或目录在不同位置之间进行快捷的引用。符号链接类似于 Windows 操作系统中的快捷方式或 MacOS 中的 alias,它们允许用户方便地访问文件或目录,而不需要在文件系统中复制文件本身。
符号链接通过保存一个指向目标文件或目录路径的文本字符串来实现间接访问。当访问符号链接时,操作系统会自动将符号链接解析为其目标路径,继而访问目标文件或目录。这种方式与硬链接不同,硬链接是通过创建一个指向相同 inode 的引用来实现的,而符号链接则是通过路径字符串来实现引用。
符号链接文件本身是一个独立的文件,它存储的路径可以指向任何文件或目录,不论该目标文件或目录是否在同一文件系统中。符号链接的创建、删除、修改与普通文件类似,但它本身只保存一个文本路径,而不是文件的数据。
在 Linux 系统中,创建符号链接通常使用 ln
命令的 -s
选项。其基本语法如下:
ln -s <目标文件> <符号链接名称>
例如,创建一个指向文件 /home/user/example.txt
的符号链接 example_link.txt
:
ln -s /home/user/example.txt example_link.txt
这个命令会在当前目录下创建一个符号链接 example_link.txt
,它指向 /home/user/example.txt
。如果访问符号链接 example_link.txt
,系统会自动解析它,并读取 /home/user/example.txt
中的内容。
如果目标是一个目录,也可以使用符号链接。例如,创建一个指向 /home/user/data
目录的符号链接:
ln -s /home/user/data data_link
-
路径引用:符号链接保存的是目标文件或目录的路径,而不是文件的实际内容。这意味着,如果目标文件被移动或删除,符号链接就会失效,变成“悬挂的”链接。
-
可跨文件系统:符号链接可以跨越不同的文件系统,指向外部设备或挂载点中的文件,而硬链接则只能在同一文件系统内创建。
-
可以指向目录:符号链接不仅可以指向文件,还可以指向目录。通过符号链接,用户可以在文件系统中创建便捷的目录访问路径。
-
符号链接本身是一个文件:符号链接是一个独立的文件,它拥有自己的 inode,且其内容是目标路径的文本字符串。
-
软链接与硬链接的区别:符号链接与硬链接的主要区别在于,硬链接是指向文件的 inode,而符号链接是指向文件路径的文本字符串。硬链接在目标文件被删除后仍然有效,因为它们指向相同的 inode,而符号链接则会失效。
查看符号链接
可以使用 ls -l
命令查看符号链接文件的详细信息。符号链接的文件类型通常以 l
开头,后面跟着符号链接的路径。示例:
ls -l example_link.txt
输出可能如下:
lrwxrwxrwx 1 user user 26 Apr 1 10:30 example_link.txt -> /home/user/example.txt
这表示 example_link.txt
是一个符号链接,指向 /home/user/example.txt
。
删除符号链接
删除符号链接可以使用 rm
命令,和删除普通文件一样:
rm example_link.txt
需要注意的是,删除符号链接只会删除链接文件本身,而不会删除目标文件。如果目标文件被删除或移动,符号链接仍然会存在,但指向的路径不再有效。
修改符号链接
修改符号链接通常意味着更新它所指向的目标文件或目录的路径。这可以通过先删除旧的符号链接,然后创建一个新的符号链接来实现:
rm example_link.txt ln -s /home/user/new_example.txt example_link.txt
符号链接在多种场景下都有应用,尤其在文件系统管理、软件安装与配置、文件访问等方面具有重要作用。
-
简化路径访问:符号链接可以简化对复杂路径的访问。例如,可以创建一个符号链接,将某个深层目录的路径简化为更容易记住的路径。
-
共享文件和资源:符号链接可以用于不同位置共享同一文件或目录。比如,多个程序可能需要访问同一个配置文件,通过符号链接可以避免复制文件并保持文件的一致性。
-
版本控制:在开发和部署过程中,符号链接可以用来指向不同版本的文件或目录。例如,可以创建一个指向最新版本的符号链接,在版本更新时只需要更新符号链接指向的目标路径,而不需要修改使用该符号链接的所有程序。
-
软件安装与配置:许多软件包在安装时会创建符号链接,以便在不同版本的文件之间切换,或者将配置文件链接到系统的标准配置位置。例如,在某些 Linux 发行版中,软件包可能会在
/usr/bin
中创建指向实际程序的符号链接。 -
跨文件系统引用:符号链接可以跨越不同的文件系统,将一个文件系统中的资源链接到另一个文件系统。例如,在多个磁盘分区中共享文件数据时,可以通过符号链接实现跨分区的文件引用。
尽管符号链接在许多情况下非常有用,但它们也有一些限制和潜在的风险:
-
悬挂链接:如果目标文件被删除或移动,符号链接将变得无效,形成悬挂链接(dangling link)。此时,访问符号链接会导致错误,程序可能无法找到目标文件。
-
循环链接:符号链接可以创建指向自身的链接,或者形成一个循环引用。这种情况下,如果程序不小心跟踪符号链接,可能会导致无限循环和栈溢出。
-
权限问题:符号链接本身具有权限设置,但在访问符号链接的目标文件时,最终的访问权限取决于目标文件的权限。如果符号链接的目标没有适当的权限,则即使符号链接本身是可访问的,访问目标文件时也会失败。
管道文件
管道文件(Pipe File)是 Linux 文件系统中的一种特殊文件类型,主要用于在不同进程之间进行通信。管道提供了一种进程间通信(IPC, Inter-Process Communication)的机制,允许一个进程的输出直接作为另一个进程的输入,进而实现数据的传递。管道文件有两种形式:匿名管道和命名管道。
管道的核心作用是允许数据在两个或多个进程之间传递,而无需将数据存储到中间文件中。它的工作原理类似于管道流体的流动:数据从一个进程流出,通过管道进入另一个进程。这种机制可以有效地实现进程间的协作,并且具有高效、低延迟的特点。
在 Linux 系统中,管道文件分为两类:匿名管道(Anonymous Pipe)和命名管道(Named Pipe)。这两者在使用方式、功能和作用上有所不同。
匿名管道(Anonymous Pipe)
匿名管道是最常见的一种管道,它在创建时没有名字,也无法在文件系统中看到,通常用于父子进程或兄弟进程之间的通信。匿名管道是由操作系统内核提供的进程间通信机制,通常通过以下两个系统调用来创建:
-
pipe()
:创建一个匿名管道,并返回一个文件描述符数组,数组的第一个元素是管道的读取端,第二个元素是管道的写入端。 -
read()
和write()
:进程通过这些系统调用从管道中读取数据或向管道中写入数据。
匿名管道的特点:
-
无名性:匿名管道并没有一个文件名,因此在文件系统中无法直接看到。它仅仅在内存中存在。
-
单向通信:管道是单向的,数据只能从写端流向读端。为了实现双向通信,必须创建两个管道,或者使用双向管道(如套接字)。
-
通常用于父子进程间通信:匿名管道通常用于父子进程或兄弟进程之间的通信,它不需要通过文件系统来共享,因此非常适用于短期和简单的通信。
-
生命周期:匿名管道的生命周期与创建它的进程相关。当管道的读写端文件描述符都被关闭时,管道就会被销毁。
使用示例:
在 Linux 中,可以通过 pipe()
函数创建匿名管道,以下是一个简单的示例:
#include <stdio.h> #include <unistd.h> #include <string.h> int main() {int pipe_fd[2];char buffer[128]; // 创建管道if (pipe(pipe_fd) == -1) {perror("pipe");return 1;} // 写端if (fork() == 0) {// 子进程向管道写入数据close(pipe_fd[0]); // 关闭读端write(pipe_fd[1], "Hello, pipe!", 13);close(pipe_fd[1]);return 0;} // 读端else {// 父进程从管道读取数据close(pipe_fd[1]); // 关闭写端read(pipe_fd[0], buffer, sizeof(buffer));printf("Received from pipe: %s\n", buffer);close(pipe_fd[0]);return 0;} }
在这个例子中,父子进程通过管道传递数据。子进程写入数据到管道,父进程从管道中读取数据。
命名管道(Named Pipe)
命名管道,通常称为 FIFO(First In, First Out),与匿名管道不同,它是有名字的管道,并且存在于文件系统中。命名管道允许不相关的进程间通信,因为它通过文件系统中的路径来标识。命名管道可以被多个进程访问,允许它们进行数据交换,特别适用于需要跨进程或跨会话的通信。
命名管道通过 mkfifo()
系统调用来创建,该调用会在文件系统中创建一个文件,作为管道的接口。
命名管道的特点:
-
命名:命名管道在文件系统中有一个路径名,这意味着可以通过文件路径来访问它。通常位于
/tmp
目录下。 -
双向通信:虽然命名管道本身是单向的,但可以通过创建两个管道,或通过其他机制实现双向通信。
-
进程间通信:命名管道允许不相关的进程进行通信。任何具有读取或写入权限的进程都可以访问命名管道。
-
存在于文件系统中:命名管道是一个实际的文件,存在于文件系统中,当管道不再被使用时,系统管理员可以删除它。
使用示例:
创建并使用命名管道的示例:
# 创建命名管道 mkfifo /tmp/my_pipe
然后,进程可以通过读写这个管道文件进行通信。例如,使用 echo
和 cat
命令:
-
在一个终端中,向命名管道写入数据:
echo "Hello, named pipe!" > /tmp/my_pipe
-
在另一个终端中,读取命名管道的数据:
cat < /tmp/my_pipe
输出:
Hello, named pipe!
在这个例子中,/tmp/my_pipe
是命名管道,数据通过该管道在两个进程之间传递。
管道的工作机制基于内核提供的缓冲区。当数据从写端写入管道时,数据首先存储在内核缓冲区中,读取端可以随时从缓冲区中取出数据。若缓冲区已满,写操作会被阻塞,直到有足够的空间;若缓冲区为空,读操作会被阻塞,直到有数据写入。
对于命名管道,文件系统会维护一个路径名,进程可以通过该路径名来访问管道。命名管道与普通文件不同,它们不存储数据,而是提供进程间通信的通道。
-
进程间通信:管道最常见的应用是进程间通信,特别是当多个进程需要共享数据时,管道提供了一种高效、简洁的方式来传递数据。
-
数据流传输:管道常用于数据流的传输,例如,在管道中传输文件内容、网络数据等。它可以简化数据流转,不需要将中间数据写入磁盘文件。
-
联合工具(pipelining):在 UNIX/Linux 系统中,管道是实现命令行工具之间协作的核心机制。多个命令可以通过管道连接,形成一个数据处理管道。例如,
ps | grep
将进程列表通过管道传递给grep
,从而筛选出匹配的进程。 -
并行处理:管道可以用于并行处理任务,在大数据处理系统中,管道提供了任务之间的高效数据传递路径,支持多进程并行计算。
管道文件存在限制:
-
缓冲区限制:管道的容量有限,默认情况下通常是 64 KB。数据写入时如果管道已满,写操作会被阻塞,直到缓冲区有空余空间。
-
单向通信:管道是单向的,通常只能从一端传输数据。如果需要双向通信,必须创建两个管道,或者使用其他机制(如套接字)来实现。
-
进程生命周期:匿名管道的生命周期通常与创建它的进程相关,当进程终止时,管道也随之销毁。
套接字文件
套接字文件(Socket File)是 Linux 文件系统中的一种特殊文件类型,用于进程间通信(IPC, Inter-Process Communication)。通过套接字文件,不同的进程可以在同一台计算机内或跨计算机进行数据交换,套接字文件不仅广泛应用于网络编程中,还可用于在本地机器上通过高效的通信协议实现进程间通信。套接字为网络通信提供了抽象接口,支持多种通信协议,主要分为两种类型:Unix 域套接字(Unix Domain Socket)和网络套接字(Network Socket)。
套接字的基本概念
套接字是操作系统提供的一种机制,用于在进程间建立双向通信通道。套接字并不像普通文件那样存储数据,而是充当数据交换的媒介。通过套接字,进程可以发送和接收数据,进程间通过套接字建立连接并交换数据。套接字文件在 Linux 文件系统中通常会表现为一个文件节点,可以通过路径来访问。
根据通信的范围和应用场景,套接字文件主要分为两类:Unix 域套接字和网络套接字。
Unix 域套接字(Unix Domain Socket)
Unix 域套接字是用于同一台机器内不同进程之间的通信。它不通过网络协议栈,而是利用操作系统内核提供的本地通信机制,因此其通信速度非常高。Unix 域套接字常常用于需要低延迟或高效通信的应用,尤其是在同一台机器上的进程间通信中。
特点:
-
高效性:由于通信不经过网络协议栈,Unix 域套接字通常比基于网络的通信更高效,延迟较低。
-
仅限本地通信:Unix 域套接字只能在同一台机器上使用,无法进行跨网络的通信。
-
文件路径标识:Unix 域套接字文件是文件系统中的一个节点,通过路径(如
/tmp/my_socket
)进行访问。
创建和使用 Unix 域套接字
-
创建套接字:使用
socket()
系统调用创建一个套接字,套接字的协议族是AF_UNIX
,通信类型通常是SOCK_STREAM
或SOCK_DGRAM
(流式套接字或数据报套接字)。 -
绑定套接字:使用
bind()
系统调用将套接字绑定到本地路径上,这个路径会成为套接字文件的位置。 -
监听和连接:服务器端调用
listen()
开始监听客户端的连接请求,客户端通过connect()
发起连接请求。 -
数据传输:数据可以通过
send()
和recv()
等系统调用在连接的套接字上进行传输。
示例代码:
服务器端(Unix 域套接字):
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> #include <string.h> #define SOCKET_PATH "/tmp/my_socket" int main() {int server_fd, client_fd;struct sockaddr_un addr;char buffer[100]; // 创建 Unix 域套接字server_fd = socket(AF_UNIX, SOCK_STREAM, 0);if (server_fd == -1) {perror("socket");exit(1);} // 绑定套接字到文件路径memset(&addr, 0, sizeof(addr));addr.sun_family = AF_UNIX;strcpy(addr.sun_path, SOCKET_PATH);if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {perror("bind");exit(1);} // 开始监听if (listen(server_fd, 1) == -1) {perror("listen");exit(1);} // 等待客户端连接printf("Waiting for connection...\n");client_fd = accept(server_fd, NULL, NULL);if (client_fd == -1) {perror("accept");exit(1);} // 接收数据read(client_fd, buffer, sizeof(buffer));printf("Received: %s\n", buffer); // 关闭套接字close(client_fd);close(server_fd);unlink(SOCKET_PATH); // 删除套接字文件 return 0; }
客户端(Unix 域套接字):
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> #include <string.h> #define SOCKET_PATH "/tmp/my_socket" int main() {int client_fd;struct sockaddr_un addr;const char *message = "Hello, server!"; // 创建套接字client_fd = socket(AF_UNIX, SOCK_STREAM, 0);if (client_fd == -1) {perror("socket");exit(1);} // 连接到服务器memset(&addr, 0, sizeof(addr));addr.sun_family = AF_UNIX;strcpy(addr.sun_path, SOCKET_PATH);if (connect(client_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {perror("connect");exit(1);} // 发送数据write(client_fd, message, strlen(message) + 1); // 关闭套接字close(client_fd); return 0; }
网络套接字(Network Socket)
网络套接字用于在不同计算机之间通过网络协议(如 TCP/IP)进行通信。它支持跨计算机通信,并且可以使用多种网络协议(如 TCP、UDP)进行数据传输。
特点:
-
跨计算机通信:网络套接字可以用于不同计算机之间的通信,通常基于 IP 地址和端口号进行标识。
-
协议支持:网络套接字支持多种通信协议,最常用的为 TCP 和 UDP。
-
可扩展性:网络套接字能够处理大规模的客户端-服务器通信,例如 Web 服务器和数据库服务器等应用。
创建和使用网络套接字
-
创建套接字:通过
socket()
系统调用创建一个网络套接字,通常使用AF_INET
或AF_INET6
协议族(IPv4 或 IPv6),SOCK_STREAM
(TCP)或SOCK_DGRAM
(UDP)通信类型。 -
绑定套接字:使用
bind()
系统调用将套接字绑定到 IP 地址和端口上,形成可识别的地址。 -
监听和连接:服务端使用
listen()
和accept()
监听客户端的连接请求,客户端使用connect()
向服务器发起连接请求。 -
数据传输:通过
send()
和recv()
或read()
和write()
系统调用进行数据传输。
示例代码:
TCP 服务器端(网络套接字):
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #define PORT 8080 int main() {int server_fd, client_fd;struct sockaddr_in addr;char buffer[1024]; // 创建套接字server_fd = socket(AF_INET, SOCK_STREAM, 0);if (server_fd == -1) {perror("socket");exit(1);} // 设置服务器地址memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_addr.s_addr = INADDR_ANY;addr.sin_port = htons(PORT); // 绑定套接字if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {perror("bind");exit(1);} // 监听连接if (listen(server_fd, 3) == -1) {perror("listen");exit(1);} // 接受客户端连接printf("Waiting for connections...\n");client_fd = accept(server_fd, NULL, NULL);if (client_fd == -1) {perror("accept");exit(1);} // 读取客户端数据read(client_fd, buffer, sizeof(buffer));printf("Received: %s\n", buffer); // 关闭套接字close(client_fd);close(server_fd); return 0; }
TCP 客户端(网络套接字):
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #define PORT 8080 int main() {int client_fd;struct sockaddr_in addr;const char *message = "Hello, server!"; // 创建套接字client_fd = socket(AF_INET, SOCK_STREAM, 0);if (client_fd == -1) {perror("socket");exit(1);} // 设置服务器地址memset(&addr, 0, sizeof(addr));addr.sin_family = AF_INET;addr.sin_port = htons(PORT);addr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 连接到服务器if (connect(client_fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {perror("connect");exit(1);} // 发送数据write(client_fd, message, strlen(message) + 1); // 关闭套接字close(client_fd); return 0; }
相关文章:
嵌入式Linux——文件类型
目录 普通文件 目录文件 目录文件的权限与管理 字符设备文件和块设备文件 符号链接文件 查看符号链接 删除符号链接 修改符号链接 管道文件 匿名管道(Anonymous Pipe) 匿名管道的特点: 使用示例: 命名管道(…...
ES6 模块化语法
目录 ES6 模块化语法 分别暴露 统一暴露 编辑 默认暴露 ES6 模块化引入方式 ES6 模块化语法 模块功能主要由两个命令构成:export 和 import。 ⚫ export 命令用于规定模块的对外接口(哪些数据需要暴露,就在数据前面加上关键字即可…...
Gradio学习笔记记录
安装指令:pip install gradio方法介绍 Interface》用于构建一些简单的页面,可以直接用这个指令搞定 形式》接收三个参数分别为处理函数、输入、输出三部分,呈现一般左/上为输入,右或下为输出 fn:将用户界面 ࿰…...
Node.js的下载与安装(支持各种新旧版本)
目录 1、node官网 2、node软件下载 3、软件安装(完整版) 1、node官网 Node.js — Download Node.jshttps://nodejs.org/en/download/package-manager 2、node软件下载 按照下图进行选择node版本(真心推荐16/18,而是尽量是LTS…...
数据库和缓存的数据一致性 -20241124
问题描述 一致性 缓存中有数据,缓存的数据值数据库中的值缓存中本没有数据,数据库中的值最新值(有请求查询数据库时,会将数据写入缓存,则变为上面的“一致”状态) “数据不一致”: 缓存的数据值…...
【计算机网络】多路转接之select
系统提供select()来实现多路转接 IO 等 拷贝 -> select()只负责等待,可以一次等待多个fd select()本身没有数据拷贝的能力,拷贝要read()/write()来完成 一、select的使用 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exc…...
Linux命令思维导图
看到一个很不错的Linux命令思维导图,用机器翻译了一下,建议收藏备用。 附上英文版:...
自然语言处理(词嵌入和词向量的使用)
一、实验目的 1.了解词嵌入和词向量的基本概念及其在自然语言处理中的应用。 2.掌握使用One-Hot编码和Word2Vec模型构建词向量的方法。 3.掌握Doc2Vec模型构建文档向量的方法以及如何计算文档向量之间的相似度。 二、实验内容 (1)使用One-Hot编码构…...
量子感知机
神经网络类似于人类大脑,是模拟生物神经网络进行信息处理的一种数学模型。它能解决分类、回归等问题,是机器学习的重要组成部分。量子神经网络是将量子理论与神经网络相结合而产生的一种新型计算模式。1995年美国路易斯安那州立大学KAK教授首次提出了量子…...
[HarmonyOS] 解决HMRouter路由地址无法抽取的问题
解决HMRouter路由地址无法抽取的问题 背景 最近开始学习HarmonyOS开发,搭建项目的时候采用了 HMRouter 路由框架,在项目里使用到路由跳转,官方链接在这: https://gitee.com/hadss/hmrouter/blob/master/HMRouterLibrary/README…...
七天掌握SQL--->第四天:事务处理与并发控制
# 7天掌握SQL - 第四天:事务处理与并发控制 ## 目标 - 学习事务处理的基本概念,如ACID特性。 - 掌握并发控制的方法,如锁机制、事务隔离级别等。 - 通过实际案例练习事务处理和并发控制。 ## 1. 事务处理的基本概念 事务处理是数据库管理系…...
Docker学习笔记整理
这周不知道写点啥内容做个分享,但还是秉持学会分享的精神,粗略放一些Docker相关的问题和解答吧,后面有机会再补补再深挖深挖o(>﹏<)o 1. 容器VS虚拟机 虚拟机是一种带环境安装的解决方案(资源完全隔离),有以下缺…...
PIMPL模式和D指针
一、PIMPL模式概念: Pimpl(pointer to implementation, 指向实现的指针)是一种用来对“类的接口与实现”进行解耦合的方法。就是将真正的实现细节的Implementor从类定义的头文件中分离出去,公有类通过一个私有指针指向隐藏的实现类…...
Linux入门系列--文件与目录
一、介绍 在Linux中,有着一句话,叫做:一切皆文件。也就是任何东西都是以文件的形式存储的。 目录结构 bin:全程binary,含义是二进制。该目录中存储的都是一些二进制文件。我们学过C/C,其实也都知道机器能…...
论文阅读——Intrusion detection systems using longshort‑term memory (LSTM)
一.基本信息 论文名称:Intrusion detection systems using longshort‑term memory (LSTM) 中文翻译:基于长短期记忆(LSTM)的入侵检测系统 DOI:10.1186/s40537-021-00448-4 作者:FatimaEzzahra Laghrissi1* , Samira Douzi2*, Kha…...
平面点排序(结构体专题)
(1) 题目描述 平面上有n个点,坐标均为整数。请按与坐标原点(0,0)距离的远近将所有点排序输出。可以自己写排序函数,也可以用qsort库函数排序。 输入描述 输入有两行,第一行是整数n(1<n<10)ÿ…...
QT 实现仿制 网络调试器(未实现连接唯一性) QT5.12.3环境 C++实现
网络调试助手: 提前准备:在编写代码前,要在.pro工程文件中,添加network模块。 服务端: 代码: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QtWidgets> #inclu…...
搜索引擎中广泛使用的文档排序算法——BM25(Best Matching 25)
在搜索场景中,BM25能计算每个文档与查询的匹配度,从中找出最相关的文档,并按相关性高低排序展示。 要理解BM25,需要掌握以下几个关键概念: 1. 词频(Term Frequency, TF):某关键词在文…...
文件上传需要考虑的安全性问题及解决方案
恶意文件上传:攻击者可能上传包含恶意代码的文件,如病毒、木马等,这些文件被服务器执行后,可能完全控制服务器或破坏服务器安全。为避免这种情况,应实施严格的文件验证策略,只允许特定的安全文件类型上传&a…...
论文笔记:Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
1. 挑战/问题(Challenges/Issues): 这篇论文探讨了大型预训练语言模型在处理知识密集型自然语言处理(NLP)任务时面临的挑战。尽管这些模型在参数中存储了大量事实知识,并在微调后能够在下游NLP任务中取得很…...
Web 网络安全
一. 浏览器系统安全方面,使用多进程方案,而js主线程运行在渲染进程中,渲染进程时运行在沙箱中的,没有对本地OS文件的直接读写权限,所以需要通过IPC与浏览器主线程通信,才可以获取cookie等信息,这…...
Android Gradle 插件和 Android Studio 兼容性
Android Gradle 插件和 Android Studio 兼容性 Android Studio 版本所需的 AGP 版本Ladybug 2024.2.13.2-8.7Ladybug 2024.2.13.2-8.7Koala 2024.1.12024.2.1Jellyfish 2023.3.12024.2.1Iguana 2023.2.13.2-8.3Hedgehog 2023.1.13.2-8.2Giraffe 2022.3.13.2-8.1Flamingo 2022.…...
C++设计模式-策略模式-StrategyMethod
动机(Motivation) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。 如何在运…...
【H2O2|全栈】JS案例章节(四)——使用原型的JS工厂模式
目录 前言 开篇语 准备工作 需求 工厂模式 概念 优点 添加元素的新方法 分析案例 HTML代码 JS实现 结束语 前言 开篇语 本系列为短章节,单独讲述部分特殊重点案例,本期讲述使用原型来实现JS的工厂模式。 与HTML和CSS相比,JS加…...
.NET9 - 新功能体验(三)
书接上回,我们继续来聊聊.NET9和C#13带来的新变化。 01、Linq新方法 CountBy 和 AggregateBy 引入了新的方法 CountBy 和 AggregateBy后,可以在不经过GroupBy 分配中间分组的情况下快速完成复杂的聚合操作,同时方法命名也非常直观࿰…...
论文概览 |《Journal of Urban Technology》2024 Vol.31 Issue.2
本次给大家整理的是《Journal of Urban Technology》杂志2024年第31卷第2期的论文的题目和摘要,一共包括6篇SCI论文! 论文1 Aerial Video Surveillance in a Megacity: A Case Study in Santiago, Chile 大城市中的空中视频监控:智利圣地亚哥…...
Makefile 之 自动化变量
作用范围只在这条规则以及连带规则中,所以其值也只在作用范围内有效。而不会影响规则链以外的全局变量的值。 "$" 表示目标的集合,就像一个数组,"$"依次取出目标,并执于命令。 "$<"和"$&qu…...
【C语言】const修饰符在指针变量中的作用详解
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C语言 文章目录 💯前言💯指针与解引用:基础概念1. 指针变量2. 解引用操作 💯const 修饰指针变量的三种主要情况1. 情况一:int * const p (指针本…...
阿里云ECS服务器监控报警配置
背景:服务器偶尔会异常,比如CPU过载,磁盘满,影响使用,人工盯服务器不现实 采用方法:阿里云监控告警功能 步骤: 第一步:登录阿里云服务器 https://account.aliyun.com/login/logi…...
高性能linux服务器运维实战小结 性能调优工具
性能指标 进程指标 进程关系 父进程创子进程时,调fork系统调用。调用时,父给子获取一个进程描述符,并设置新的pid,同事复制父进程的进程描述符给子进程,此时不会复制父进程地址空间,而是父子用相同地址空…...
初识Linux—— 基本指令(下)
前言: 本篇继续来学习Linux的基础指令,继续加油!!! 本篇文章对于图片即内容详解,已同步到本人gitee:Linux学习: Linux学习与知识讲解 Linux指令 1、查看文件内容的指令 cat cat 查看文件…...
【Linux】线程的互斥和同步
【Linux】线程的互斥和同步 线程间的互斥 临界资源:多线程执行共享的资源就叫做临界资源临界区:每个线程内部,访问临界资源的代码,就叫做临界区互斥:任何时刻,互斥保证有且只有一个执行流进入临界区&#…...
详解Oracle表的类型(二)
1.引言: Oracle数据库提供了多种表类型,以满足不同的数据存储和管理需求。本博文将对Oracle分区表及使用场景进行详细介绍。 2. 分区表 分区表是Oracle数据库中一种重要的表类型,它通过将表数据分割成多个逻辑部分来提高查询性能、管理灵活…...
VSCode 下载 安装
VSCode【下载】【安装】【汉化】【配置C环境(超快)】(Windows环境)-CSDN博客 Download Visual Studio Code - Mac, Linux, Windowshttps://code.visualstudio.com/Downloadhttps://code.visualstudio.com/Download 注意࿰…...
java中的最小堆
概述 最小堆minHeap指的级别n的每个节点存储的值小于或等于级别n1的子节点的值。因此,根就存储了其中最小的值。 注意节点的值与其他兄弟节点的值之间没有必然关系。 java中最小堆的表示 利用数组 常用的是利用数组minHeap[]表示,将最小堆的节点或值…...
ES实用面试题
一、es是什么,为什么要用它? ES通常是Elasticsearch的简称,它是一个基于Lucene构建的开源搜索引擎。Elasticsearch以其分布式、高扩展性和实时数据分析能力而闻名,广泛用于全文搜索、日志分析、实时监控等多种场景。 基本特点&am…...
数据结构 (7)线性表的链式存储
前言 线性表是一种基本的数据结构,用于存储线性序列的元素。线性表的存储方式主要有两种:顺序存储和链式存储。链式存储,即链表,是一种非常灵活和高效的存储方式,特别适用于需要频繁插入和删除操作的场景。 链表的基本…...
数据结构:链表进阶
链表进阶 1. ArrayList的缺陷2. 链表2.1 链表的概念及结构2.2 链表的实现 3.链表面试题4.LinkedList的使用5.1 什么是LinkedList4.2 LinkedList的使用 5. ArrayList和LinkedList的区别 1. ArrayList的缺陷 通过源码知道,ArrayList底层使用数组来存储元素࿱…...
Can UDS 学习记录
目录 Can UDS 学习记录10 03 响应否定响应22和24 的说明27服务肯定响应抑制位 Can UDS 学习记录 10 03 响应 否定响应22和24 的说明 0x22条件不正确,就是不满足服务端的运行条件0x24请求顺序错误;停止例程的请求必须在开始例程后面才可以,请…...
C 语言实现的优先级队列
C 语言实现的优先级队列 priorityqueue.h /******************************************************************************* * Copyright © 2024-2025 Light Zhang <mapawarehotmail.com>, MapAware, Inc. * * ALL RIGHTS RESERVED. …...
卷积神经网络(CNN)中的批量归一化层(Batch Normalization Layer)
批量归一化层(BatchNorm层),或简称为批量归一化(Batch Normalization),是深度学习中常用的一种技术,旨在加速神经网络的训练并提高收敛速度。 一、基本思想 为了让数据在训练过程中保持同一分布…...
HDR视频技术之四:HDR 主要标准
HDR 是 UHD 技术中最重要维度之一,带来新的视觉呈现体验。 HDR 技术涉及到采集、加工、传输、呈现等视频流程上的多个环节,需要定义出互联互通的产业标准,以支持规模化应用和部署。本文整理当前 HDR 应用中的一些代表性的国际标准。 1 HDR 发…...
下一个阶段的生产工具更换:
开源竞争: 当你无法彻底掌握技术的时候,就开源这个技术,让更多的人了解这个技术,形成更多的技术依赖,你会说,这不就是在砸罐子吗?一个行业里面总会有人砸罐子的,你不如先砸罐子&…...
性能优化--CPU微架构
一 指令集架构 Intel X86, ARM v8, RISC-V 是当今广泛使用的指令架构的实例。 大多数现代架构可以归类为基于通用寄存器的加载和存储型架构,在这种架构下,操作数倍明确指定,只能使用夹在和存储指令访问内存。除提供基本的功能之外,…...
3.3_1 差错控制(检错编码)
目录 1、差错来源 全局性 局部性 2、数据链路的差错控制 编辑奇偶校验码 CRC循环冗余码 接收端检错过程 1、差错来源 概括来说,传输中的差错都是由于噪声引起的。 全局性 由于线路本身电气特性所产生的随机噪声(热噪声),是信道固有的…...
2024年wordpress、d-link等相关的多个cve漏洞poc
⚠️ 漏洞 ✅ CVE-2024-10914 在D-Link DNS-320、DNS-320LW、DNS-325和DNS-340L中发现的漏洞,版本直到20241028 GET /cgi-bin/account_mgr.cgi?cmdcgi_user_add&name%27;id;%27 HTTP/1.1✅ CVE-2024-11305 在Altenergy Power Control Software中发现的关键…...
影视后期学习Ⅰ~
1.DV是光盘 磁带 2.序列就是我们要制作的一个视频。 打开界面显示: 一号面板放的是素材,二号面板叫源监视器面板(它的名字需要记住)在一号面板点击文件之后,进入二号面板,在二号面板预览没问题后…...
如何安全删除 Linux 用户帐户和主目录 ?
Linux 以其健壮性和灵活性而闻名,是全球服务器和桌面的首选。管理用户帐户是系统管理的一个基本方面,包括创建、修改和删除用户帐户及其相关数据。本指南全面概述了如何在 Linux 中安全地删除用户帐户及其主目录,以确保系统的安全性和完整性。…...
【软件测试】设计测试用例的万能公式
文章目录 概念设计测试用例的万能公式常规思考逆向思维发散性思维万能公式水杯测试弱网测试如何进行弱网测试 安装卸载测试 概念 什么是测试用例? 测试⽤例(Test Case)是为了实施测试⽽向被测试的系统提供的⼀组集合,这组集合包…...
【MySQL】字符集与排序规则
1. 字符集 1.1 一些重要的字符集 1.1.1 ASCII 共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。由于总共才128个字符,所以可以使用1个字节来进行编码 1.1.2 ISO-8859-1 共收录 256 个字符,是在 ASCII 字符集的基…...