Linux应用

news2026/5/6 21:57:34
指令常用的Linux指令ls命令执行什么功能可以带哪些参数功能列出指定目录中的目录以及文件参数-a显示所有文件及目录.开头的隐藏文件也会列出-l除文件名外亦将文件型态、权限、拥有者、文件大小等资讯详细列出-r将文件以相反次序显示原定英文字母次序-t将文件依建立时间先后次序列出-A同-a但不列出“.”目前目录及..父目录-F在列出的文件名称后加一符号。可执行档* 目录/-R若目录下有文件则以下之文件皆依次列出创建文件vi或vimtouchechovi file1.txt #直接创建并打开一个文件file1.txttouch file2.txt #创建新的空文件file2.txtecho this is a new file file3.txt #创建文件file3.txt并将this is a new file写入说明使用指令覆盖文件原内容并重新输入内容若文件不存在则创建文件。echo add contents file3.txt#在已存在的文件补充写入新内容add contents说明使用指令向文件追加内容原内容将保存。lessmorecat三者都是将文件内容输出到标准输出,其中less和more和分页显示cat是显示全部三者可以根据以及存在的文件创建新的文件假设已经存在文件1.txtcat 1.txt 2.txtless 1.txt 3.txtmore 1.txt 4.txtmore 命令只能向前翻页无法向后翻页。用户只能使用Enter键和空格键向后翻动页面。而less命令则更加灵活用户可以使用上下箭头键或jk键在文件中上下翻动。cd 最主要的作用是切换目录在 cd 后面跟或再加上文件名就可以创建一个内容为空的文件。它和echo 的区别之处在于 echo 可写文件内容而cd并不能。cd file3.txt #创建新的空文件file3.txtcd file4.txt #创建新的空文件file4.txt创建目录mkdir runoob#在工作目录下建立一个名为 runoob 的子目录mkdir -p runoob2/test #在工作目录下的 runoob2 目录中建立一个名为 test 的子目录。若runoob2 目录原本不存在则建立一个。注本例若不加 -p 参数且原本 runoob2 目录不存在则产生错误。查看文件内容有哪些命令vi 文件名 #编辑方式查看可修改cat 文件名 #显示全部文件内容more 文件名 #分页显示文件内容less 文件名 #与 more 相似更好的是可以往前翻页tail 文件名 #仅查看尾部还可以指定行数head 文件名 #仅查看头部,还可以指定行数查找文件内容用哪个命令grep test *file #在当前目录中查找后缀有 file 字样的文件中包含 test 字符串的文件并打印出该字符串的行grep -r update /etc/acpi #查找指定目录/etc/acpi 及其子目录如果存在子目录的话下所有文件中包含字符串update的文件grep -v test *test* #查找文件名中包含 test 的文件中不包含 test 的行-n 选项表示输出匹配行的行号。-w 选项表示只匹配整个单词而不是字符串的一部分。-r 选项表示递归搜索子目录。-v 用于排除匹配的行即显示不包含指定模式的行查找文件用哪个命令find . -name *.c #将当前目录及其子目录下所有文件后缀为 .c 的文件列出来find . -ctime -20 #将当前目录及其子目录下所有最近 20 天内更新过的文件列出查看内存磁盘占用内存占用free -h系统相关RAM使用情况物理内存、交换内存top查看系统CPU、进程、内存使用情况1磁盘占用df -h查看磁盘占用常用的GCC指令编译四个阶段预处理Pre-Processing、编译Compiling、汇编Assembling、链接Linking#include stdio.h#define PI 3.14159int main(){printf(PI %f\n, PI);return 0;}预处理对源代码进行文本替换和宏展开生成一个纯 C/C 代码gcc -E test.c -o test.i #把预处理的结果导出到test.i文件宏替换#define头文件包含#include条件编译#ifdef#ifndef#endif删除注释行号标记用于调试tsst.i# 1 test.c# 1 built-in# 1 command-line# 1 test.c# 1 /usr/include/stdio.h 1 3 4... (stdio.h 的内容被展开)# 3 test.c 2int main(){printf(PI %f\n, 3.14159);return 0;}编译将预处理后的代码翻译成汇编代码gcc -S test.i -o test.s #编译器将test.i翻译成汇编语言并将结果存储在test.s文件中。词法分析Lexical Analysis语法分析Syntax Analysis语义分析Semantic Analysis优化生成汇编代码test.s.file test.c.section .rodata.LC0:.string PI %f\n.text.globl main.type main, functionmain:pushq %rbpmovq %rsp, %rbpmovl $.LC0, %edimovsd .LC1(%rip), %xmm0movl $1, %eaxcall printfmovl $0, %eaxpopq %rbpret.size main, .-main.section .rodata.align 8.LC1:.long 1374389535.long 1074339512.ident GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0.section .note.GNU-stack,,progbits汇编将汇编代码转换为机器码 .o 或 .obj 文件gcc -c test.s - o test.o #将汇编代码编译为目标文件.o但不链接逐行解析汇编指令生成目标文件包含机器码、符号表、重定位信息链接将多个目标文件合并并解析外部引用库函数生成可执行文件.exe或a.outgcc test.o -o test #将生成的目标文件test.o生成最终的可执行文件test一步到位编译gcc test.c -o test #将源文件test.c编译链接为可执行文件test多文件编译gcc test1.c test2.c -o test警告处理gcc -w test.c -o test # 忽略编译时的警告gcc -Wall test.c -o test #编译后显示所有警告gcc -Werror test.c -o test #在产生警告的地方停止编译常用的GDB调试指令开启调试gcc -g -o test test.cgdb testl n显示行号b n断点设置info b查看断点信息d Num / d breakpoints删除指定 / 所有断点enable / disable b Num开启 / 禁用 全部断点指定断点rrun无断点直接运行到程序结束加上断点去运行的话就会在打的断点处停下来nnext逐过程sstep逐语句一次走一条代码可进入函数同时库函数也会进入p(print) 变量名 打印变量值display跟踪查看一个变量每次停下来都显示它的值【变量/结构体…】undisplay 变量名编号取消跟踪until 行号运行指定行finish在一个函数内部执行到当前函数返回然后停下来等待命令c(continue) 从一个断点处直接运行至下一个断点处bt 查看底层函数调用的过程【函数压栈】常用的驱动开发指令加载/卸载驱动insmod/modprobe #加载驱动rmmod #卸载驱动Linux驱动如何查看驱动模块中打印信息dmesg如何查看内核中已有的字符设备的信息lsmod 和modprobelsmod可以查看模块的依赖关系modprobe在加载模块时会加载其他依赖的模块。如何创建设备mknod /dev/zgl c 240 0 #用于创建一个名为/dev/zgl的字符设备文件。其中c表示字符设备类型240是主设备号0是次设备号。如何查看设备号cat /proc/devices如何查看正在使用的有哪些中断号cat /proc/interrupt文件I/O和标准I/O文件I/O与标准I/O的区别文件 I/OInput/Output也称为低级 I/O它是操作系统提供的基本 I/O 操作接口直接对文件描述符进行操作。文件描述符是一个非负整数用于标识一个打开的文件。在 Unix/Linux 系统中像open、read、write、close等系统调用都属于文件 I/O 操作。标准 I/O也称为高级 I/O它是在文件 I/O 的基础上构建的一种更为方便的 I/O 库。标准 I/O 提供了缓冲机制它会自动为输入输出操作分配缓冲区减少系统调用的次数提高效率。在 C 语言中stdio.h头文件中定义的函数如printf、scanf、fgets、fputs等都属于标准 I/O。标准I/O常用APIfopenFILE *fopen (const char *__restrict __filename,const char *__restrict __modes)参数解析char *__restrict __filename: 字符串表示要打开文件的路径和名称char *__restrict __modes: 字符串表示访问模式(1)r: 只读模式 没有文件打开失败(2)w: 只写模式 存在文件写入会清空文件,不存在文件则创建新文件(3)a: 只追加写模式 不会覆盖原有内容 新内容写到末尾如果文件不存在则创建(4)r: 读写模式 文件必须存在 写入是从头一个一个覆盖(5)w: 读写模式 可读取,写入同样会清空文件内容不存在则创建新文件(6)a: 读写追加模式 可读取,写入从文件末尾开始如果文件不存在则创建return: FILE * 结构体指针 表示一个文件fopen函数主要用来打开一个文件第一个参数表示打开的文件路径和名称第二个参数表示文件访问模式例如可读或者可写或者创建文件等调用成功后放回一个结构体指针表示一个文件。fcloseint fclose (FILE *__stream)参数解析FILE *__stream: 需要关闭的文件return: 成功返回0 失败返回EOF(负数) 通常失败会造成系统崩溃fclose函数主要用来关闭一个指定的文件调用成功后返回0fputcint fputc (int __c, FILE *__stream)参数解析int __c: 写入的char按照AICII值写入 可提前声明一个charFILE *__stream: 要写入的文件,写在哪里取决于访问模式return: 成功返回char的值 失败返回EOFfputc函数主要用来写入一个字符到指定的文件流第一个参数填写字符例如A第二个参数填写文件。fputsint fputs (const char *__restrict __s, FILE *__restrict __stream)参数解析char *__restrict __s: 需要写入的字符串FILE *__restrict __stream: 要写入的文件,写在哪里取决于访问模式return: 成功返回非负整数(一般是0,1) 失败返回EOFfputs函数主要用来写入一个字符串到指定的文件流第一个参数填写字符例如ABC第二个参数填写文件。fprintffprintf (FILE *__restrict __stream, const char *__restrict __fmt, ...)参数解析FILE *__restrict __stream: 要写入的文件,写在哪里取决于访问模式char *__restrict __fmt: 格式化字符串...: 变长参数列表return: 成功返回正整数(写入字符总数不包含换行符) 失败返回EOF示例File *file fopen(example.txt, w);// 写入格式化的数据int age 25;char name[] Alice;fprintf(file, Name: %s, Age: %d\n, name, age);fprintf函数主要用来将格式化的数据写到指定的文件流中第一个参数填写文件第二个参数填写格式化字符串第三个参数填写参数列表比如整型%d字符型%c字符串型%s参数。fgetcint fgetc (FILE *__stream)参数解析FILE *__stream: 需要读取的文件return 读取的一个字节 到文件结尾或出错返回EOFfgetc函数主要用来读取指定文件中的一个字节。fgetschar *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)参数解析char *__restrict __s: 接收读取的数据字符串int __n: 能够接收数据的长度FILE *__restrict __stream: 需要读取的文件return: 成功返回字符串 失败返回NULL(可以直接用于while)示例#include stdio.hint main(){char buffer[100]; // 定义一个足够大的缓冲区printf(请输入一行文本最多99个字符\n);// 从标准输入读取字符串if (fgets(buffer, sizeof(buffer), stdin) ! NULL){printf(您输入的内容是\n%s, buffer);}else{printf(读取输入失败。\n);}return 0;}fgets函数主要用来读取一个字符串第一个参数是接收读取的字符串buf第二个参数是数据的长度第三个是读取的文件成功返回字符串失败返回NULL。fcanfint fscanf (FILE *__restrict __stream, const char *__restrict __format, ...)参数解析FILE *__restrict __stream: 读取的文件char *__restrict __format: 读取的匹配表达式...: 变长参数列表 用于接收匹配的数据return: 成功返回参数的个数 失败返回 0 报错或结束返回EOF示例#include stdio.hint main(){int age;float height;char name[50];printf(请输入您的姓名、年龄和身高格式姓名 年龄 身高\n);// 从标准输入读取格式化的数据if (fscanf(stdin, %s %d %f, name, age, height) 3){printf(您输入的信息是\n);printf(姓名%s\n, name);printf(年龄%d\n, age);printf(身高%.2f\n, height);}else{printf(输入格式错误。\n);}return 0;}fscanf函数主要用来从指定的文件流中读取格式化的数据第一个参数是指定的文件流第二个参数填写格式化字符串第三个参数填写参数列表比如整型%d字符型%c字符串%s参数。标准输入输出错误stdin: 标准输入FILE *stdout: 标准输出FILE * 写入这个文件流会将数据输出到控制台stderr: 错误输出FILE * 一般用于输出错误日志文件 I/O 常用API文件I/O常见APIopenint open (const char *__path, int __oflag, ...);参数解析const char *__path: 文件路径int __oflag: 用于指定打开文件的方式,可以是以下选项的组合:(1) O_RDONLY: 以只读方式打开文件(2) O_WRONLY: 以只写方式打开文件(3) O_RDWR: 以读写方式打开文件(4) O_CREAT: 如果文件不存在,则创建一个新文件(5) O_APPEND: 将所有写入操作追加到文件的末尾(6) O_TRUNC: 如果文件存在并且以写入模式打开,则截断文件长度为0还有其他标志,如O_EXCL当与O_CREAT一起使用时,只有当文件不存在时才创建新文件、O_SYNC同步I/O、O_NONBLOCK非阻塞I/O等可选参数: mode - 仅在使用了O_CREAT标志且文件尚不存在的情况下生效,用于指定新创建文件的权限位 权限位通常由三位八进制数字组成,分别代表文件所有者、同组用户和其他用户的读写执行权限return: (1) 成功时返回非负的文件描述符。(2) 失败时返回-1并设置全局变量errno以指示错误原因。open函数主要用来打开一个指定的文件第一个参数是文件的路径路径可以是绝对路径或者相对路径第二个参数是指定打开文件的方式可以是只读只写或者可读可写等第三个参数只有在第二个参数选择创建文件才生效用来指定新创建文件的权限位权限位通常由三位八进制数字组成,分别代表文件所有者、同组用户和其他用户的读写执行权限。readssize_t read (int __fd, void *__buf, size_t __nbytes);参数解析int __fd:一个整数,表示要从中读取数据的文件描述符void *__buf:一个指向缓冲区的指针,读取的数据将被存放到这个缓冲区中size_t __nbytes:一个size_t类型的整数,表示要读取的最大字节数 系统调用将尝试读取最多这么多字节的数据,但实际读取的字节数可能会少于请求的数量return: (1) 成功时,read()返回实际读取的字节数 这个值可能小于__nbytes,如果遇到了文件结尾EOF或者因为网络读取等原因提前结束读取(2) 失败时,read()将返回-1read函数主要用来从指定的文件描述符中读取数据第一个参数为指定的文件描述符第二个参数存放读取数据的buf第三个数据表示读取的字节数。writessize_t write (int __fd, const void *__buf, size_t __n);参数解析int __fd:一个整数,表示要写入数据的文件描述符void *__buf:一个指向缓冲区的指针,写入的数据需要先存放到这个缓冲区中size_t __n:一个size_t类型的整数,表示要写入的字节数 write()函数会尝试写入__n个字节的数据,但实际写入的字节数可能会少于请求的数量return: (1) 成功时,write()返回实际写入的字节数 这个值可能小于__n,如果写入操作因故提前结束,例如: 磁盘满、网络阻塞等情况(2) 失败时,write()将返回-1write函数主要用来从指定的文件描述符中写入数据第一个参数为指定的文件描述符第二个参数存放写入数据的buf第三个数据表示写入的字节数。closeint close (int __fd);参数解析int __fd:一个整数,表示要关闭的文件描述符return: (1) 成功关闭时 返回0(2) 失败时 返回-1close函数主要用来关闭使用完的文件描述符。exit()和_exit()通常在父进程中使用 exit() 以确保程序在退出前能执行清理操作如关闭文件和刷新输出。在子进程中使用 _exit() 这可以防止子进程的终止影响到父进程比如防止子进程意外地刷新了父进程未写入的输出缓冲区进程进程是资源分配的基本单位在程序运行时创建PCB进程控制块进程控制块PCB Process Control Block通过一个结构体存放进程运行的相关信息例如进程id进程的状态进程的物理内存和虚拟内存进程运行的时间进程所执行程序的路径进程五种状态进程可以分为五个状态分别是1. 创建状态2. 就绪状态3. 运行状态4. 阻塞状态5. 终止状态创建状态一个应用程序从系统上启动首先就是进入创建状态需要获取系统资源创建进程控制块完成资源分配。就绪状态在创建状态完成之后进程已经准备好但是还未获得处理器资源无法运行。运行状态获取处理器资源被系统调度开始进入运行状态。如果进程的时间片用完了就进入就绪状态。阻塞状态在运行状态期间如果进行了阻塞的操作如耗时的I/O操作此时进程暂时无法操作就进入到了阻塞状态在这些操作完成后就进入就绪状态。终止状态进程结束或者被系统终止进入终止状态进程的状态转换图进程的状态转换图fork和vfork区别fork( )的子进程有自己独立的地址空间拷贝父进程的代码段、数据段、堆、栈等vfork( )的子进程与父进程共享地址空间包括代码段、数据段、堆、栈等fork( )的父子进程的执行次序不确定vfork( )保证子进程先运行在它调用exec或exit之后父进程才可能被调度运行。僵尸进程孤儿进程守护进程用 fork 函数创建一个正常运行的子进程子进程 0父进程 0如果子进程退出父进程没有及时调用wait或 waitpid 函数回收子进程的系统资源该进程就变成僵尸进程如果系统收回了就是正常退出如果父进程退出了但是子进程还在该进程就变成孤儿进程被 init 收养如果父进程是故意被杀掉子进程做相应处理后就是守护进程进程间通信管道无名管道无名管道是一种单向的、字节流的通信管道它是一种匿名管道无法通过文件系统来访问它只能通过文件描述符在具有亲缘关系的进程之间使用比如父子进程和兄弟进程。无名管道通信步骤创建一个函数创建无名管道pipe()创建子进程fork()父子进程共享管道的读写端。在父进程中关闭管道的读端向管道的写端写入数据。在子进程中关闭管道的写端从管道的读端读取数据。如果要双向传输的话就多创建一个管道控制好父子进程管道的读写段即可。有名管道有名管道与无名管道不同它是通过文件系统路径命名的管道可以在进程之间进行通信消息队列消息队列是一种先进先出的消息缓冲区用于在多个进程之间传递消息。消息队列通信步骤创建或获取一个进程间通信键值 IPC keyftok()创建或打开一个消息队列 msgget()进程通过消息队列发送消息msgsnd()进程通过消息队列接收消息msgrcv()删除消息队列msgctl()缺点消息队列的缓存区域是在内核空间中开辟的因此当进程发送或接收消息时需要经过内核态和用户态之间的多次切换多次状态间的切换会带来一定的开销特别是在发送和接收大量数据时切换开销可能会严重影响系统性能。共享内存共享内存是通过操作系统内核在不同进程之间共享内存区域的一种机制。在创建共享内存时操作系统会分配一块内存区域并将其映射到各个进程的地址空间中。进程可以直接读写这个内存区域而不需要进行任何数据传输的操作。共享内存的优点是速度快因为不需要数据的复制操作而且不需要操作系统进行上下文切换所以它通常比其他 IPC 机制如管道和消息队列更快共享内存通信步骤创建或获取一个进程间通信键值 IPC keyftok()创建共享内存shmget()将共享内存映射到进程的地址空间中shmat()解除共享内存映射shmdt()删除共享内存shmctl()信号量信号量既可用于进程间同步也可用于临界区资源的互斥访问。当多个线程出现后可能会遇到无序执行的问题和同时操作临界公共资源的问题就可以用信号量通过 PV 操作来阻塞或者唤醒某个线程控制线程的执行顺序。信号量通信步骤创建或获取一个进程间通信键值 IPC keyftok()创建或获取信号量semget()初始化信号量semctl()P 操作等待/ V 操作释放semop()删除信号量semctl()线程对于进程而言每一个进程都有一个唯一对应的PID号来表示该进程而对于线程而言也有一个“类似于进程的PID号”名为tid其本质是一个pthread_t类型的变量。线程号与进程号是表示线程和进程的唯一标识但是对于线程号而言其仅仅在其所属的进程上下文中才有意义。线程使用首先需要创建线程一旦线程创建完成后线程与线程之间会发生竞争执行抢占时间片来执行线程逻辑。在创建线程时候可以通过创建线程的第四个参数传入参数在线程退出时亦可传出参数被线程回收函数所回收获取到传出的参数。互斥量当多个线程出现后会遇到同时操作临界公共资源的问题当线程操作公共资源时需要对线程进行保护加锁防止多个线程同时修改一个变量等到该线程执行完毕后再次解锁使其余线程再度开始竞争。互斥锁创建流程下图所示。信号量当多个线程出现后同时会遇到无序执行的问题。有时候需要对线程的执行顺序做出限定便引入了信号量通过PV操作来控制线程的执行顺序。自旋锁、互斥锁、读写锁自旋锁是一种基于忙等待的锁机制。当一个线程尝试获取自旋锁时如果锁已经被其他线程占用它不会进入休眠状态而是不断地循环检查锁是否被释放。自旋锁适用于锁持有时间非常短的场景如果锁的持有时间较长自旋锁会浪费大量的CPU资源导致系统性能下降。互斥锁是一种用于保护共享资源的锁机制。它确保同一时间只有一个线程可以持有该锁从而保证对共享资源的互斥访问。当一个线程尝试获取互斥锁时如果锁已经被其他线程占用它会进入休眠状态等待锁被释放。一旦锁被释放线程会被唤醒并尝试获取锁。读写锁是一种允许多个线程同时读取共享资源但写操作需要互斥的锁机制。它分为读锁和写锁。读锁允许多个线程同时持有读锁但不允许写锁持有。写锁是互斥的同一时间只能有一个线程持有写锁且写锁持有期间不允许其他线程持有读锁。网络编程TCP/UDPTCP怎么保证可靠性1. 序列号、确认应答、超时重传数据到达接收方接收方需要发出一个确认应答表示已经收到该数据段并且确认序号会说明它下一次需要接收的数据序列号。如果发送方迟迟未收到确认应答那么可能是发送的数据丢失也可能是确认应答丢失这时发送方在等待一定时间后会进行重传。这个时间一般是2*RTT(报文段往返时间一个偏差值。2. 窗口控制与高速重发控制/快速重传重复确认应答TCP会利用窗口控制来提高传输速度意思是在一个窗口大小内不用一定要等到应答才能发送下 一段数据窗口大小就是无需等待确认而可以继续发送数据的最大值。如果不使用窗口控制每一个没收到确认应答的数据都要重发。使用窗口控制如果数据段1001-2000丢失后面数据每次传输确认应答都会不停地发送序号为 1001的应答表示我要接收1001开始的数据发送端如果收到3次相同应答就会立刻进行重发 但还有种情况有可能是数据都收到了但是有的应答丢失了这种情况不会进行重发因为发送端知道如果是数据段丢失接收端不会放过它的会疯狂向它提醒。简述一下TCP建立连接和断开连接的过程TCP建立连接和断开连接的过程三次握手TCP传输控制协议三次握手是TCP协议建立连接的过程其主要目的是确保双方在通信之前已经准备好并且能够互相通信。三次握手主要是客户端发起连接请求服务器响应连接请求客户端确认连接以下是三次握手的详细过程1. 客户端主动方向服务器被动方发送一个SYN同步序列编号报文段。这个报文段的SYN标志位被置为1同时携带一个随机的序列号Seq x。这个序列号是客户端为这次连接生成的初始序列号。例如客户端生成的初始序列号是1000那么这个SYN报文段的序列号就是1000。2. 服务器收到客户端的SYN报文段后如果同意建立连接会发送一个SYN - ACK同步 - 确认报文段作为响应。这个报文段的SYN标志位和ACK确认标志位都被置为1。服务器会为这个连接分配资源并且生成自己的初始序列号Seq y。同时它会将客户端的初始序列号x加1后作为确认号ACK x 1发送给客户端。例如服务器的初始序列号是2000客户端的初始序列号是1000那么服务器发送的SYN - ACK报文段的序列号是2000确认号是1001。3. 客户端收到服务器的SYN - ACK报文段后会发送一个ACK确认报文段给服务器。这个报文段的ACK标志位被置为1序列号是客户端的初始序列号加1Seq x 1确认号是服务器的初始序列号加1ACK y 1。例如客户端的初始序列号是1000服务器的初始序列号是2000那么客户端发送的ACK报文段的序列号是1001确认号是2001。四次挥手TCP四次挥手是TCP协议关闭连接的过程其目的是确保双方在关闭连接之前已经完成了数据的传输并且能够安全地释放资源四次挥手主要是客户端发起关闭请求服务器确认客户端的关闭请求服务器发起关闭请求客户端确认服务器的关闭请求以下是四次挥手的详细过程1. 客户端主动关闭方向服务器被动关闭方发送一个FIN结束报文段表示客户端已经完成了数据的发送想要关闭连接。这个FIN报文段的FIN标志位被置为1同时携带一个序列号Seq u。这个序列号是客户端在连接建立过程中生成的序列号随着数据的发送和确认序列号会不断变化。例如客户端在连接过程中发送了多个数据报文段当前的序列号是3000那么这个FIN报文段的序列号就是3000。2. 服务器收到客户端的FIN报文段后会发送一个ACK确认报文段给客户端。这个ACK报文段的ACK标志位被置为1序列号是服务器当前的序列号Seq v确认号是客户端的序列号加1ACK u 1。例如服务器当前的序列号是4000客户端的序列号是3000那么服务器发送的ACK报文段的序列号是4000确认号是3001。3. 服务器在确认客户端的关闭请求后会等待一段时间这个时间是服务器自己决定的用于处理一些后续的事务比如数据的清理等。然后服务器也会发送一个FIN报文段给客户端表示服务器也完成了数据的发送想要关闭连接。这个FIN报文段的FIN标志位被置为1序列号是服务器的序列号加1Seq v 1。例如服务器的序列号是4000那么这个FIN报文段的序列号就是4001。4. 客户端收到服务器的FIN报文段后会发送一个ACK报文段给服务器。这个ACK报文段的ACK标志位被置为1序列号是客户端的序列号加1Seq u 1确认号是服务器的序列号加1ACK v 2。例如客户端的序列号是3000服务器的序列号是4000那么客户端发送的ACK报文段的序列号是3001确认号是4002。TCP的三次握手和四次握手的原因是什么为什么是三次握手1. TCP连接是双向的客户端和服务器都可以发送和接收数据。三次挥手可以确保双方都完成了数据的发送。为了防止已失效的客户端连接请求报文段突然又送到服务器因而产生错误。2. 在网络中可能存在延迟、丢包等情况假设客户端发送连接请求后因网络延迟很久才到达服务器或者客户端发送连接请求后出现问题突然下线如果只有两次握手服务器会误认为是一个新的连接请求而建立连接这会导致无效连接浪费资源。通俗来讲过程就像打电话1. 第一次握手 (客户端 - 服务器)客户端“喂你好听得到吗” ( SYN )客户端心里想我的消息发出去试试看对方在不在线线路通不通。2. 第二次握手 (服务器 - 客户端)服务器“哎我听得到你呢听得到我吗” ( SYN-ACK )服务器心里想我不仅收到了你的问候我也回应了并且也反问一下你确认你也能听到我。3. 第三次握手 (客户端 - 服务器)客户端“嗯我也听得到你那我们开始聊正事吧” ( ACK )客户端心里想太好了对方能听到我我也能听到对方沟通渠道完全畅通为什么是四次挥手1. TCP协议是全双工通信客户端和服务器都可以发送和接收数据。四次挥手可以确保双方都完成了数据的发送。2. 假设是三次挥手时首先释放了客户端到服务器方向的连接此时TCP连接处于半关闭Half-Close状态 这时客户端不能向服务器发送数据而服务器还是可以向客户端发送数据。如果此时客户端收到了服务器的确认报文段后就立即发送一个确认报文段这会导致服务器向客户端还在发送数据时连接就被关闭。这样会导致客户端没有完整收到服务器所发的报文段过程就像打完电话要挂断1. 第一次挥手 (客户端 - 服务器)客户端“嗯我要说的都说完了我准备挂电话了哈。” ( FIN )客户端说完了但它还可以接收数据。2. 第二次挥手 (服务器 - 客户端)服务器“哦哦好的我知道你说完了。你稍等一下我看看我这边还有没有要对你说的。”( ACK )服务器先给客户端一个确认但自己可能还有数据没发送完。3. 第三次挥手 (服务器 - 客户端)服务器“好了我这边也都说完了我也准备挂电话了。” ( FIN )服务器处理完所有数据也告知客户端自己说完了。4. 第四次挥手 (客户端 - 服务器)客户端“好的那我们拜拜啦” ( ACK )客户端收到服务器的结束请求最后确认一下然后双方正式挂断。为什么必须四次三次不行吗因为 TCP 连接是全双工的——就好比电话通话你可以同时听我说我也可以同时听你说。挂电话时必须双方都确认说完了才行。第二次和第三次挥手不能合并吗有时候可以但通常不行。因为当客户端说“我说完了”时服务器可能还有数据要发送给客户端。所以服务器要先回复一个“我知道你说完了”第二次挥手然后赶紧把没说完的数据发完最后再说“我也说完了”第三次挥手。这两个动作中间是有时间差的。TCPUDP的区别1. TCP 是面向连接的UDP 是面向无连接的2. TCP 是面向字节流的UDP 是基于数据报的3. TCP 保证数据正确性UDP 可能丢包4. TCP 保证数据顺序UDP 不保证TCPUDP的优缺点和适用场景TCP传输数据比较可靠稳定但是效率比较低占用系统资源高一般使用在文件传输发送邮件等场景。UDP传输数据不可靠不稳定但是速度比较快效率比较高一般使用在语音电话视频聊天等场景偶尔丢包卡顿不要紧TCP相比UDP为什么是可靠的1. 确认和重传机制建立连接时三次握手同步双方的“序列号 确认号 窗口大小信息”是确认重传、流控的基础传输过程 中如果Checksum校验失败、丢包或延时发送端重传。2. 数据排序TCP有专门的序列号SN字段可提供数据re-order3. 流量控制窗口和计时器的使用。TCP窗口中会指明双方能够发送接收的最大数据量。4. 拥塞控制TCP的拥塞控制由4个核心算法组成。“慢启动”Slow Start、“拥塞避免”Congestionavoidance、“快速重传 ”Fast Retransmit、“快速恢复”Fast Recovery基于TCP的socket编程服务端1. socket2. bind3. listen4. accept5. send / recv write / read6. close服务端程序先用socket函数创建一个套接字然后再用 bind 函数将 IP 地址和端口绑定在这个套接字上用 listen 函数设置允许的最大连接数用 accept 函数接收客户端上的连接然后用 send 或者write 函数发送数据用 recv 或者 read 函数接收数据最后记得用 close 函数关闭网络连接。客户端1. socket2. connect3. send / recvread / write4. close客户端程序先用socket函数创建一个套接字设置要连接的对方的IP地址和端口等属性接着用 connect函数连接服务器然后用 send 或者 write 函数发送数据用 recv 或者 read 函数接收数据最后记得用close 函数关闭网络连接。基于UDP的socket编程服务端1. socket2. bind3. sendto4. recvfrom5. close服务端程序先用socket函数创建一个套接字然后再用 bind 函数将 IP 地址和端口绑定在这个套接字上使用 sendto 函数发送数据使用 recvfrom 函数接收数据最后用 close 函数关闭网络连接。客户端1. socket2. sendto3. recvfrom4. close客户端程序先用socket函数创建一个套接字设置要连接的对方的IP地址和端口等属性然后使用sendto 函数发送数据使用 recvfrom 函数接收数据最后用 close 函数关闭网络连接。HTTP什么是HTTP协议HTTP协议是Hyper Text Transfer Protocol超文本传输协议的缩写是用于从万维网WWW:World Wide Web服务器传输超文本到本地浏览器的传送协议。HTTP协议适用于CS架构和BS架构浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后向客户端发送响应信息。CS架构是一种典型的两层结构包括客户端和服务器两个部分。在这种架构中客户端和服务器通过网络进行通信每部分都有明确的职责。BS架构是一种基于Web的三层或多层架构主要通过Web浏览器作为客户端访问服务器上的应用程序。HTTP和HTTPS的区别HTTPS有什么优缺点区别1. HTTP协议是以明文的方式在网络中传输数据而HTTPS协议传输的数据则是经过TLS加密后的HTTPS具有更高的安全性2. HTTPS在TCP三次握手阶段之后还需要进行 SSL 的handshake协商加密使用的对称加密密钥3. HTTPS协议需要服务端申请证书浏览器端安装对应的根证书4. HTTP协议的默认端口是80HTTPS协议的默认端口是443HTTP建立连接过程是什么HTTP 请求/响应的步骤如下1. 客户端连接到Web服务器2. 发送HTTP请求3. 服务器接受请求并返回HTTP响应4. 释放连接TCP连接5. 客户端浏览器解析HTML内容HTTP协议定义Web客户端如何从Web服务器请求Web页面以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行作为响应响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据IO模型IO 操作就是计算机的输入输出操作在冯.诺依曼结构中将计算机分成了5个部分分别是运算器、控制器、存储器、输入设备和输出设备上图中的输入设备指的是鼠标和键盘等向计算机输入数据和信息的设备输出设备指的是电脑显示器等用于计算机信息输出的设备。当敲击键盘输入设备任意按键后按键的数据会传递给计算机计算机CPU会对数据进行运算运算完成之后会将数据输出到显示器输出设备上。IO执行过程在Linux 操作系统中内核负责对计算机的资源进行管理和对进程进行调度。应用程序运 行于用户空间而IO操作往往涉及硬件由于硬件操作需要特权级权限必须由操作系统在 内核空间中完成。也就是说应用程序不能直接对硬件进行操作只能通过内核提供的系统调 用接口如read、write等间接完成IO操作。此外用户空间无法直接访问内核空间的数据 因此在IO操作完成后内核需要将数据从内核空间拷贝到用户空间供应用程序使用。一个完整的IO过程需要包含以下三个步骤用户空间的应用程序向内核发起IO调用请求(系统调用)内核操作系统准备数据把IO设备的数据加载到内核缓冲区操作系统拷贝数据把内核缓冲区的数据拷贝到用户进程缓冲区IO模型分类在实际开发中IO操作常常成为影响程序性能的关键因素。假设有一个场景从磁盘读取 100MB 数据并处理读取数据耗时20秒处理数据也需要20秒。如果采用最传统的顺序流程——读取完再处理那么整个流程耗时约40秒效率明显偏低。那么能不能在等待数据的同时对数据进行处理呢这时候就轮到IO编程模型来出场了。IO 模型根据实现的功能可以划分为阻塞IO、非阻塞IO、信号驱动IO、IO多路复用和异步 IO。根据等待IO的执行结果进行划分前四个IO模型又被称为同步IO同步IO与异步IO是数据处理中的两种重要模式同步是指应用发起IO请求后必须等待内核完成数据准备和传输操作才能继续执行后 续任务。在此过程中应用可能会被阻塞直到数据从内核空间拷贝到用户空间。异步IO允许应用在发起IO请求后立即返回并继续执行其他任务。内核会在数据准备好并完成传输后通过回调或信号通知应用操作已完成。应用无需主动等待数据的准备过程。同步IO查询方式非阻塞APP调用open函数时传入“O_NONBLOCK”表示“非阻塞”。APP调用read函数读取数据时如果驱动程序中有数据那么APP的read函数会返回数据否则也会立刻返回错误休眠-唤醒方式阻塞APP调用open函数时不要传入“O_NONBLOCK”。APP调用read函数读取数据时如果驱动程序中有数据那么APP的read函数会返回数据否则APP就会在内核态休眠当有数据时驱动程序会把APP唤醒read函数恢复执行并返回数据给APP。IO多路复用IO 多路复用是一种同时监视多个文件描述符的技术它可以通过单个进程来处理多个 IO 操作提高系统的 IO 效率。在 IO 多路复用中一个进程可以同时监视多个文件描述符一旦其中任意一个文件描述符准备就绪就会通知进程进行读写操作从而实现了同时处理多个 IO 事件的功能。以select()函数为例进行讲解使用时需要向select()传入待监听的文件描述符集合以及超时时间。当执行select()时系统会触发一次系统调用内核将遍历检查这些描述符是否触发了目标事件如可读、可写。若检测到事件则立即返回若未检测到事件进程将进入阻塞状态并休眠直到任一描述符就绪或超时为止。当select()返回后用户空间需遍历所有描述符逐一确认具体是哪个触发了事件从而实现单线程同时管理多个 IO 操作的效果。缺点select 监听的描述符有上限一般描述符最大不超过1024而且需要遍历究竟是哪 一个IO产生了数据。因此IO较多时效率不高所以可以使用 epoll信号驱动IO异步通知信号驱动IO指的是进程会预先告知内核当某个描述符发生事件时内核要向该进程发送 SIGIO 信号进行通知进程可以在信号处理函数中对该事件进行处理。要使用信号驱动IO需要应用程序和驱动程序配合应用程序使用信号驱动IO的步骤有三步注册信号处理函数应用程序中使用signal()函数来注册SIGIO信号的信号处理函数。使用fcntl()函数设置能够接收这个信号的进程。使用fcntl()函数的F_SETFL参数打开FASYNC标志开启信号驱动IO。异步通知方式首先要注册信号处理函数和编写信号处理函数当驱动程序用数据时会主动发信号给应用程序从而调用信号处理函数。1.编写信号处理函数static void sig_func(int sig){int val;read(fd, val, 4);printf(get button : 0x%x\n, val);}2.注册信号处理函数signal(SIGIO, sig_func);3.打开驱动fd open(argv[1], O_RDWR);4.把进程 ID 告诉驱动// 设置该文件描述符的拥有者为该进程fcntl(fd, F_SETOWN, getpid());5.使能驱动的 FASYNC 功能// 获取文件描述符的状态标志flags fcntl(fd, F_GETFL);// 设置文件描述符的状态标志fcntl(fd, F_SETFL, flags | FASYNC);异步IOaio_read() 函数常常用于异步IO当进程使用aio_read()读取数据时如果数据尚未准备就绪就立即返回不会阻塞。若数据准备就绪就会把数据从内核空间拷贝到用户空间的缓冲区中 然后执行定义好的回调函数对接收到的数据进行处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2589486.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…