![](https://img-blog.csdnimg.cn/20210714010836232.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
Linux环境编程
文章平均质量分 89
记录Linux环境下系统编程和网络编程的知识要点。
code_peak
这个作者很懒,什么都没留下…
展开
-
对于APUE中信号的 #define SIG_ERR (void(*)())-1 的理解
在学习 APUE 的信号章节中,我们知道 Linux 中最简单的信号接口如下:#include <signal.h>void (*signal(int signo, void (*func)(int)))(int);//返回值:若成功,返回以前的信号处理配置;若出错,返回 SIG_ERR参数:signo:上面给出的信号名。func:常量值 SIG_IGN、常量 SIG_DEL 或当接到此信号后要调用的函数的地址。如果指定 SIG_IGN,则向内核表示忽略此信号(但是信号 SIGK原创 2021-09-08 23:46:36 · 355 阅读 · 0 评论 -
POSIX信号量
信号量概念信号量(semaphore)是一种用于提供不同进程间或一个给定进程的不同线程间同步手段的原语。POSIX 有如下类型的信号量:Posix 有名信号量:使用 Posix IPC 名字标识,可用于进程或线程间的同步。Posix 基于内存的信号量(无名信号量):存放在共享内存区中,可用于进程或线程间的同步。暂时只考虑不同进程间的同步。首先考虑二值信号量:其值或为 0 或为 1 的信号量。如下图:该信号量是由内核来维护的(这对于 SystemV 信号量是正确的),其值可以是0或1。Posix转载 2021-07-13 00:23:02 · 1905 阅读 · 0 评论 -
POSIX共享内存
共享内存概念共享内存区是可用IPC形式中最快的。一旦这样的内存区映射到共享它的进程的地址空间,这些进程间数据的传递就不再涉及内核。然而往该共享内存区存放信息或从中取走 信息的进程间通常需要某种形式的同步。如: 互斥锁、条件变量、读写锁、信号量。其“不再涉及内核”的含义是:进程不再通过执行任何进入内核的系统调用来彼此传递数据。显然,内核必须建立允许各个进程共享该内存区的内存映射关系,然后一直管理该内存区(处理页面故障等)。Posix 消息队列可使用内存映射 I/O(mmap 函数)实现。假设 Pos转载 2021-07-13 00:23:28 · 751 阅读 · 0 评论 -
POSIX消息队列
消息队列概念消息队列可以看作一个消息链表,有足够写权限的线程可往队列中放置消息,有足够读权限的线程可从队列中取走消息。每个消息都是一个记录,它由发送者赋予一个优先级。在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达(恰好与 PIPE 和 FIFO 相反,因为管道中除非读出者已存在,否则先有写入者是没有意义的)。一个进程可以往某个队列写入一些消息,然后终止,再让另外一个进程在以后某个时刻读出这些消息。因为消息队列具有随内核的持续性,和管道和 FIFO 不一样,管道的最后一次关转载 2021-07-12 23:04:24 · 600 阅读 · 0 评论 -
POSIX管道
PIPE(无名管道)管道是最初的 Unix IPC 形式,其局限在于其没有名字,只能由有亲缘关系的进程使用。PIPE 使用常用的 read 和 write 函数访问。所有的 Unix 都提供无名管道,提供一个单向数据流(半双工),但是有些版本的 Unix 提供全双工管道。#include <unistd.h>int pipe(int fd[2]); //返回值:成功为0,出错为-1如下展示了单个进程中管道的模样,从图中可以看到,fd[0] 用于读,称为读端,fd[1] 用于写,称为写端转载 2021-07-12 22:56:44 · 221 阅读 · 0 评论 -
IPC进程间通信概念
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》Posix 和 SystemV 的区别参考:https://blog.csdn.net/derkampf/article/details/60958086Posix 是“可移植操作系统接口”(Portable Operating System Interface)的首字母缩写。 它并不是一个单一标准,而是一个由电气与电子工程师学会即IEEE开发的一系列标准。 Posix 标准还是由 ISO(国际标准化组织)和 IEC(国际电工委员会)采纳的国转载 2021-07-12 22:36:42 · 175 阅读 · 0 评论 -
UNIX域套接字
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》概述Unix域套接字不是一个协议族,是单个主机上进程间通信的一种方法。它提供了两类套接字:字节流套接字和数据报套接字,类似于TCP和UDP套接字。虽然socket套接字可用于同一目的,但UNIX域套接字的效率更高。UNIX域套接字仅仅复制数据,它们并不执行协议处理,不需要添加或删除网络报头,无需计算检验和,不要产生顺序号,无需发送确认报文。Unix域套接字提供流和数据报两种接口。UNIX域数据报服务是可靠的,既不会丢失消息也不会传递出错。U转载 2021-07-12 22:23:08 · 925 阅读 · 0 评论 -
ioctl函数操作描述符
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》ioctl 是设备驱动程序中设备控制接口函数,一个字符设备驱动通常会实现设备打开、关闭、读、写等功能,在一些需要细分的情境下,如果需要扩展新的功能,通常以增设 ioctl() 命令的方式实现。服务器编程中经常使用 ioctl 获取所在主机全部网络接口的信息,比如:接口地址是否支持广播、是否支持多播等。ioctl 函数函数定义:#include <unistd.h>int ioctl(int fd, int request,转载 2021-07-12 22:18:55 · 243 阅读 · 0 评论 -
recvmsg和sendmsg函数
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》之前的 recv 函数中介绍到,其 flags 参数在设计上存在一个基本问题:它是按值传递的,而不是一个值-结果参数。但是 recvmsg 和 sendmsg 所用的 msghdr 结构,该结构是按引用传递的,内核返回时会修改其中的 msg_flags 成员标志,如果一个进程需要内核更新标志,就需要调用 recvmsg,而不是调用 recv 或 recvfrom。其实这两个函数也是最通用的 I/O 函数,事实上可以把所有的 read、readv转载 2021-07-12 21:46:25 · 1616 阅读 · 0 评论 -
readv和writev函数
这两个函数类似于 read 和 write 函数,但是其允许单个系统调用读入或写出多个缓冲区。这些操作分别称为分散读和集中写,因为来自读操作的输入数据被分散到多个应用缓冲区中,而来自多个应用缓冲区的输出数据集则被几种提供给单个写操作。其函数签名如下:#include <sys/uio.h>ssize_t readv(int fd, const struct iovec *iov, int iovcnt);ssize_t writev(int fd, const struct iovec *转载 2021-07-12 21:37:01 · 2645 阅读 · 0 评论 -
套接字中read/write和send/recv函数
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》write 和 read 函数一旦,我们建立好了 TCP 连接之后,我们就可以把得到的 fd 当作文件描述符来使用。由此网络程序里最基本的函数就是 read 和 write 函数了。其定义如下:#include <unistd.h>ssize_t read(int fd, void *buf, size_t count);ssize_t write(int fd, const void *buf, size_t count);转载 2021-07-12 21:29:57 · 1046 阅读 · 0 评论 -
TCP带外数据
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》参考:《UNIX环境高级编程》带外数据概念带外数据(out-of-band data)是一些通信协议所支持的可选功能,与普通数据相比, 它允许更高优先级的数据传输。带外数据先行传输,即使传输队列已经有数据。TCP 支持带外数据,但是 UDP 不支持。套接字接口对带外数据的支持很大程度上受 TCP 带外数据具体实现的影响。假设一个进程已经往一个 TCP 套接字写出 N 字节数据,而且 TCP 把这些数据排队在该套接字的发送缓冲区中,等着发送到转载 2021-07-12 21:25:19 · 626 阅读 · 0 评论 -
socket编程种名字与地址转换函数
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》之前都是使用数值地址来表示主机(比如:127.0.0.1),用数值端口号来标识服务器(比如:6379)。但是有时候最好使用名字而不是数值:名字比较容易记住,数值地址容易变动,而名字地址保持不变;随着 IPv6 上转移,数值地址变得很长,手工键入数值容易出错。之后将有一系列函数用于名字、数值、端口之间的转换。gethostbyname & gethostbyaddr 函数gethostbyname 函数查找主机名字最基本的函数时 g转载 2021-07-12 01:31:35 · 308 阅读 · 0 评论 -
sockopt套接字选项操作
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》获取和设置套接字选项的方法:getsockopt 和 setsockfopt函数fcntl 函数ioctl 函数getsockopt & setsockopt函数这两个函数仅用于套接字。#include <sys/socket.h>int getsockopt(int sockfd, int level, int optname, void* optval, socklen_t* optlen);int转载 2021-07-11 18:20:45 · 1431 阅读 · 0 评论 -
IO多路服用epoll
epoll 基本知识epoll 是 linux2.6 内核的一个新的系统调用,是之前 select、poll 的增强版本。epoll 更加灵活没有描述符限制,使用一个 epoll 文件描述符管理多个描述符,将用户关心的文件描述符的事件存放到内核的一个事件表中,这样只需要在用户空间和内核空间拷贝一次,因此 epoll 在高性能服务器领域应用广泛。epoll 相关接口需要的头文件:#include <sys/epoll.h>需要的函数:int epoll_create(int size原创 2021-07-11 17:51:38 · 197 阅读 · 0 评论 -
IO多路服用poll
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》pollpoll 提供了与 select 相似的功能,不过在处理流设备时,能提供额外的信息。poll相关接口需要的头文件:#include <poll.h>需要的函数:int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);fdarray 是指向结构体 struct pollfd 数组第一个元素的指针。每个数组元素都是一个 pollfd 结构转载 2021-07-11 17:44:17 · 105 阅读 · 0 评论 -
POSIX的pselect函数
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》pselect 函数pselect 函数是由 POSIX 发明的,如今许多 Unix 变种都支持它。pselect 函数原型:#include <sys/select.h>#include <signal.h>#include <time.h>int pselect(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, c转载 2021-07-11 17:39:50 · 352 阅读 · 0 评论 -
IO多路复用select
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》IO复用概念在网络编程中,我们需要一种预先告知内核的能力,使得内核一旦发现进程指定的一个或多个 I/O 条件就绪,就通知进程,这个能力叫 IO 复用,一般由 select 或 poll 两个函数支持,但是还有比较新的 pselect 的POSIX变种。最后还有更高级的平台相关的 epoll 和 kqueue 以及 windwos 的 IOCP 等。select 函数select 允许进程指示内核等待多个事件中的任何一个发生,并在有一个或多个原创 2021-07-11 17:31:12 · 280 阅读 · 0 评论 -
五种IO模型比较
五种I/O模型在 Unix 下可用的 5 种 I/O 模型:阻塞式IO、非阻塞式IO、IO复用、信号驱动IO、异步IO。一个输入操作通常包括两个不同的阶段:等待数据准备好从内核向进程复制数据阻塞式IO最流行的 IO 模型是阻塞式 IO 模型如下:在该图中,进程调用 recvfrom,其系统调用直到数据报到达且被复制到应用进程的缓冲区中或者发生错误才返回。最常见的错误是系统调用被信号中断。我们说进程从调用 recvfrom 开始到他返回的整段时间内是被阻塞的。recvfrom 成功返回后,转载 2021-07-11 17:16:19 · 308 阅读 · 0 评论 -
TCP的半关闭、半连接、半打开
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》如果将客户端与服务器之间的网络作为全双工管道来考虑,请求是从客户端向服务器发送,应答是从服务器向客户端发送,其如下图所示:上图假设 RTT 为 8,且服务器没有处理时间且请求大小与应答大小相同。既然从管道发出到管道的另一端存在延迟,而管道是全双工的,仅仅使用了管道的 1/8,对于停-等方式对于交互式输入是合适的。如果以批量的方式输入,客户端以网络可接受的最快速度持续发送请求,服务器也以相同的速度处理它们并发回应答。这就将导致在时刻7的时候,原创 2021-07-11 16:51:59 · 1368 阅读 · 0 评论 -
UDP套接字编程
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》UDP 与 TCP 之间传输存在差异,也导致编写应用程序存在很多差异。UDP 客户端和服务器不建立连接,而是直接使用 sendto 函数给服务器发送数据报。但必须指定目的地的地址作为参数。服务器也不用接受客户端的连接,而是直接调用 recvfrom 函数,等待来自某个客户的到达。recvform 将所接收的数据报和协议地址返回来。UDP 典型交互图:recvfrom 和 sendto 函数这两个函数类似于 read 和 write 函数,原创 2021-07-11 16:39:07 · 4084 阅读 · 0 评论 -
TCP套接字编程
参考:《UNIX 网络编程 · 卷1 : 套接字联网API》基本的套接字编程socket函数想要执行网络 I/O,首先需要调用 socket 函数创建套接字,需要头文件 #include <sys/socket.h>int socket (int domain, int type, int protocol);参数:domain: 执行协议域,取值如下:domain说明AF_INETIPV4协议AF_INET6IPV6协议AF_LOCAL原创 2021-07-11 16:17:24 · 463 阅读 · 0 评论 -
Socket编程基本概念
用户数据报协议(UDP)UDP 是一个简单的传输层协议,当应用层向 UDP 套接字写入一个消息,此消息会被封装到一个 UDP 数据报,进而又被封装到一个 IP 数据报发送到目的地。UDP 不保证数据报会到达目的地,不保证多个数据报的先后顺序,不保证每个数据报只到达一次。UDP 提供无连接的服务,因为 UDP 客户端与服务器之间不存在任何长连接关系。传输控制协议(TCP)完全不同于 UDP,TCP 提供了可靠性传输。TCP 需要客户端与服务器之间建立连接,然后通过这个连接进行交换数据,最后终止连接。转载 2021-07-11 00:10:30 · 287 阅读 · 0 评论