Unix/Linux编程
文章平均质量分 83
使用语言C/C++进行Unix/Linux编程,包括系统编程、网络编程、TCP/IP协议栈的实现和使用技巧
OceanStar的学习笔记
这个作者很懒,什么都没留下…
展开
-
Linux C/C++编程:获取每s的时钟滴答
#include <stdio.h>#include <stdlib.h>#include <unistd.h>unsigned int system_hz;void get_system_HZ() { long ticks; if ((ticks = sysconf(_SC_CLK_TCK)) == -1) { printf("Cannot get system clock ticks"); exit(-1)转载 2021-01-04 20:33:41 · 719 阅读 · 0 评论 -
C/C++编程:为什么需要内存池
为什么需要内存池#include <iostream>#include <time.h>class CTestClass{ char m_chBuf[4096];};int main(){ clock_t count = clock(); for(unsigned int i=0; i<0x5fffff; i++){ CTestClass *p = new CTestClass; delete p;转载 2020-12-08 13:48:03 · 1186 阅读 · 0 评论 -
Linux C/C++编程:(pid_t)syscall(SYS_gettid)
syscall理论用户应用可以通过两种方式使用系统调用。第一种方式是通过C库函数,包括系统调用在C库中的封装函数和其他普通函数。第二种方式是使用_syscall宏。2.6.18版本之前的内核,在include/asm-i386/unistd.h文件中定义有7个_syscall宏,分别是:_syscall0(type,name) _syscall1(type,name,type1,arg1) _syscall2(type,name,type1,arg1,type2,arg2)转载 2021-01-01 16:21:27 · 6839 阅读 · 0 评论 -
Linux C/C++编程:prctl与pthread_setname_np
prctl理论// 用 prctl 给线程命名, prctl是个系统调用#include <sys/prctl.h> int prctl(int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);实践#include <zconf.h>#include <sys/prctl.h>#include <stdio.h>#转载 2021-01-01 19:04:32 · 4541 阅读 · 0 评论 -
C/C++编程:高性能服务器程序框架
服务器模型CS模型TC/IP协议在设计和实现上没有客户端和服务器的概念,在通信过程中所有机器都是对等的。但是由于资源(视频、新闻、软件等)都被数据提供者垄断,因此几乎所有的网络程序都采用了CS模型:所有客户端都通过访问服务器来获取所需的资源:服务器启动后,首先创建一个或者多个监听socket,并调用bind函数将其绑定到服务器感兴趣的断开上,然后调用listen函数等待客户连接服务器稳定运行之后,客户端就可以调用connect函数向服务器发起连接了由于客户请求连接时随机到达的异步事件,服务器就需转载 2021-01-04 10:32:31 · 983 阅读 · 0 评论 -
Linux C/C++编程:读写锁
读锁也叫做”共享锁“,写锁叫做”独占锁“读写锁API如何操作锁#include <pthread.h>/** 获取一个读锁:* * 如果该锁正在写,阻塞调用线程*/int pthread_rwlock_rdlock (pthread_rwlock_t *__rwlock)/** 获取一个写锁:* * 如果该锁正在写,阻塞调用线程* * 如果该锁正在读,阻塞调用线程*/int pthread_rwlock_wrlock (pthread_rwlock_.转载 2020-11-24 11:58:44 · 1411 阅读 · 0 评论 -
Linux C/C++编程:TCP带外数据
首先给出OSI参考模型与TCP/IP协议模型图:概述首先,我们需要知道的是数据分两种,一种是带内数据,一种是带外数据。 带内数据就是我们平常传输或者说是口头叫的数据。带外数据就是我们接下来讲的内容。许多的传输层都具有带外数据(也就是经加速数据)的概念,想法就是连端发生了重要的事情,希望迅速的通知给对端。这里的迅速是指这种通知应该在已经排队了的带内数据之前发送。也就是说,带外数据具有更高的优先级。带外数据不要求再启动一个连接进行传输,而是使用已有的连接进行传输。为什么需要带外数据有时数据 会以转载 2020-12-29 15:27:04 · 703 阅读 · 0 评论 -
Linux C/C++编程:打开读取关闭目录
理论#include<sys/types.h>#include<dirent.h>/** 功能: 打开一个目录,在失败的时候返回一个空的指针。* 参数: 路径名* 返回值:指向目录流 (directory stream) 的指针(执行path目录下所有文件和目录的列表)* 错误代码:* 1、EACCESS 权限不足。* 2、EMFILE 已达到进程可同时打开的文件数上限。* 3、ENFILE 已达到系统可同时打开的文件数上限转载 2020-12-28 10:13:36 · 612 阅读 · 0 评论 -
Linux C/C++编程:lseek、fseek、ftell、rewind、fgetpos、fsetpos、
rewind、fseek、ftell为C库函数,lseek为系统函数/** 功能: 设置文件位置为给定流 stream 的文件的开头* 参数: stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流*/void rewind(FILE *stream)#include <stdio.h>/** 功能: 返回给定流 stream 的当前文件位置。* 参数: stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了流。* 返回值.转载 2020-12-28 11:08:08 · 3507 阅读 · 0 评论 -
Linux C/C++编程: 文件操作open/close、fopen与freopen/fclose
open是linux下的底层系统调用函数,fopen与freopen c/c++下的标准I/O库函数,带输入/输出缓冲。linxu下的fopen是open的封装函数,fopen最终还是要调用底层的系统调用open。所以在linux下如果需要对设备进行明确的控制,那最好使用底层系统调用(open)open对应的文件操作有:close, read, write,ioctl 等。fopen 对应的文件操作有:fclose, fread, fwrite, freopen, fseek, ftell, re转载 2020-12-25 17:51:21 · 9035 阅读 · 0 评论 -
深入理解计算机系统: 系统IO
引入输入/输出 (1 0) 是在主存和外部设备(例如磁盘驱动器、终端和网络)之间复制数据的过程输入操作是从 设备复制数据到主存输出操作是从主存复制数据到 1/0 设备所有语言的运行时系统都提供执行 的较高级别的工具 例如:ANSI 提供标准库,包含像 printf scanf 这样执行带缓冲区的 函数。C++ 语言用它的重载操作符 << (输入)和>>(输出)提供了类似的功能。在 Linux 系统中,是通过使用由内核提供的系统级 UnixI/O 函数来 实现这些较高级别的 I/0 函数的转载 2020-12-28 11:31:54 · 805 阅读 · 0 评论 -
C/C++编程:线程私有空间封装
基础linux多线程之线程私有存储空间1、Posix 标准下 “动态 TLS 模型” 使用举例:#include <stdlib.h>#include <stdio.h>#include <pthread.h>static pthread_key_t key;// 每个线程退出时回调此函数来释放线程局部变量的动态分配的内存static void destructor(void *arg){ free(arg); printf("des转载 2020-12-21 15:33:49 · 312 阅读 · 0 评论 -
C/C++编程:eventfd 的分析与具体例子
理论Linux 2.6.27后添加了一个新的特性,就是eventfd,是用来实现多进程或多线程的之间的事件通知的,也可以由内核通知用户空间应用程序事件。。接口eventfd的创建是通过eventfd函数实现的,返回值即是该eventfd所对应的文件描述符,函数的原型如下所示:#include <sys/eventfd.h>int eventfd(unsigned int initval, int flags);initval:创建eventfd时它所对应的64位计数器的初始值;f转载 2020-12-15 15:10:59 · 5432 阅读 · 0 评论 -
unix环境高级编程出错函数
【代码】unix环境高级编程出错函数。转载 2020-12-08 09:42:30 · 158 阅读 · 0 评论 -
Linux C/C++编程:利用Socket编写获取时间服务器
服务器 与客户端客户段与服务器使用TCP在同一个以太网(局域网)中通信客户端和服务器一般是用户进程,而TCP/I[协议通常是内核中协议栈的一部分客户段与服务器使用TCP在不同以太网(局域网)中通信这两个局域网是使用路由器(router)连接到广域网(WAN)的路由器是广域网的架设设备当今最大的广域网是因特网获取时间时间获取客户端用于获取时间服务IPV4版本#include <stdlib.h>#include <stdio.h>#in转载 2020-12-04 20:27:31 · 1894 阅读 · 0 评论 -
Linux C/C++编程:netstat分析tcp状态转移(socket通信)
服务器正常启动服务器启动之后,调用socket、bind、listen和accept,并且阻塞与accept调用(此时还没有客户端启动)。在启动客户端之前,我们先调用nestat程序来检查服务器监听套接字的状态$ ./AAA &[1] 9044$ netstat -a | grep 9877tcp 0 0 0.0.0.0:9877 0.0.0.0:* LISTEN从上面我们可以看出,有一个套接字处于LIST原创 2020-12-10 21:44:26 · 1397 阅读 · 0 评论 -
Linux C/C++编程:《UNIX环境高级编程》第三版源码编译centos7
下载源代码http://apuebook.com/code3e.html解压$ tar -xvf src.3e.tar.gz$ cd apue.3e/$ cat README Read the file called DISCLAIMER.On Freebsd, type "gmake".On other platforms, type "make" (as long as this is gnu make).For FAQs, updated source code, a..转载 2020-11-24 17:23:05 · 289 阅读 · 0 评论 -
Linux C/C++编程:Udp组播(多播)
Udp多播简介转载 2020-10-27 15:30:28 · 8117 阅读 · 3 评论 -
Linux C/C++编程:unix网络编程卷二环境搭建
编译原书所带例子:wget http://www.kohala.com/start/unpv22e/unpv22e.tar.gz解压:tar -zxvf unpv22e.tar.gz3. 编译:$cd unpv22e$ ./configure$ cd lib$ makegcc -g -O2 -D_REENTRANT -Wall -D_POSIX_PTHREAD_SEMANTICS -c -o daemon_inetd.o daemon_inetd.c In file in.转载 2020-11-20 15:11:46 · 497 阅读 · 0 评论 -
Unix/Linux编程:UDP可靠传输协议之KCP的实现原理与应用
为什么要做UDP可靠性传输如何做到可靠性传输做到可靠性传输,可以通过如下机制实现(1)延迟ACK机制发送端将数据发送出去之后,需要等待对方的确认应答如果有确认应答,说明数据已经成功到达对端如果没有收到应答,不能说数据一定丢失了,但是数据丢失的可能性比较大注意: nagle算法和ack是冲突的,对时延敏感的应用会禁用nagle算法(2)重传机制数据重传,是发送端发送数据之后如果没有收到对端ACK,那么继续重发数据常用方式是在重发数据之前,等待确认应答来指定超时时间,如果超过了该转载 2022-02-16 00:05:27 · 1781 阅读 · 0 评论 -
Unix/Linux编程:可靠UDP传输模块应该怎么设计
什么时候有可能采用UDP通信而不是TCP更好首先,不要在UDP协议上实现一个可靠传输协议,即类似 TCP over UDP的东西。TCP已经够复杂了,几乎不太可能重新设计得更好。如果用UDP再实现一个可靠传输协议,而表现的比TCP效果更好,那么多半只是在部分情况下有优势,或者是霸道的占用了过量的资源,而TCP在设计时是很友好的,以整个网络的通畅为更高准则的。如果大家都想独占网络带宽,那么只会让每个人都无法获得高质量通讯。在网络游戏里,不断有人期望基于UDP协议通讯来获得更快的响应速度,而又想让通转载 2021-10-10 13:08:07 · 225 阅读 · 0 评论 -
Unix/Linux编程:网络编程封装总结
网络编程原则明确:网络IO的职责也就是说,封装是可以从两个层面来封装,一个是从操作IO的层面,比如各种接收、发送数据格式,监听数据流等,一个是从检测IO层面,也叫做事件引擎,专门用来检测IO事件。比如redis的封装层面如下:ps,粘包问题是在【IO操作层】解决的:所谓粘包,就是多个包可能合并成一个包发送,需要分开了解决的关键在于想办法从收到的数据报中将包与包之间的边界区分出来,主要有三种方法:只发送固定包长度的数据报以指定字符(串)为包的结束标记包头+包体格式:包头是固定大小的,转载 2022-02-15 15:22:42 · 192 阅读 · 0 评论 -
Unix/Linux编程:服务器模型Reactor和Proactor
网络IO,会涉及到两个系统对象,一个是用户空间调用IO的进程或者线程,另一个是内核空间的内核系统,比如发生IO操作read时,它会经历两个阶段等待数据准备就绪将数据从内核拷贝到进行或者线程中因为在以上两个阶段各有不同的情况,所以出现了多种网络IO模型服务器模型Reactor和Proactor对高并发编程,网络连接上的消息处理,可以分为两个阶段:等待消息准备好消息处理当使用默认的阻塞套接字时(例如上面提到的 1 个线程捆绑处理 1 个连接),往往是把这两个阶段合二为一,这样操作套接字的转载 2021-09-22 10:29:31 · 590 阅读 · 0 评论 -
Unix/Linux编程:五种I/O模型
阻塞IO在Linux中,默认情况下所有的socket都是阻塞的,一个典型的读操作流程如下:第一步通常涉及等待数据从网络中到达。当所有等待数据到达时,它被复制到内核中的某个缓冲区第二步就是把数据从内核缓冲区复制到用用程序缓冲区当用户进程调用recvfrom这个系统调用时,kernel就开始了IO的第一个阶段:准备数据,就是数据被拷贝到内核缓冲区中的一个过程(很多网络IO数据不会那么快到达,如没收一个完整的UDP包),等数据到操作系统内核缓冲区了,就到了第二阶段:将数据从内核缓冲区拷贝到用户内存,转载 2020-12-28 20:08:41 · 683 阅读 · 2 评论 -
Unix/Linux编程:为什么要引入多种IO模型
概述一般情况下,单个进程上每次只在一个文件描述符上执行IO操作,每次 I/O 系统调用都会阻塞直到完成数据传输。比如,当从一个管道中读取数据时,如果管道中恰好没有数据,那么通常 read()会阻塞。而如果管道中没有足够的空间保存待写入的数据时,write()将会阻塞。当其他类型的文件比如FIFO和套接字上出现IO操作时,也会出现相似的行为磁盘文件是个特例。内核采用缓冲区cache来加速磁盘IO请求。因而一旦请求的数据传输到内核的缓冲区cache,对磁盘的write()操作将会立即返回,而不用等到将数据转载 2021-06-10 15:28:08 · 230 阅读 · 0 评论 -
Unix/Linux编程:信号驱动IO
信号驱动IO在IO多路复用中,进程是通过系统调用(select、epoll)来检测文件描述符上是否可以执行IO。而在信号驱动IO中,进程请求内核当文件描述符上可执行IO操作时为自己发送一个信号。之后进程就可以执行任何其他的任务直到IO就绪为止。要使用信号驱动IO,程序需要按照如下步骤执行为内核发送的通知信号安装一个信号处理例程。默认情况下,这个通知信号为SIGIO设定文件符的属主,也就是当文件描述符山可执行IO时会接收通知信号的进程或进程组。通常我们让调用进程成为属主。设定属主可通过 fcntl()转载 2021-06-10 17:47:28 · 1290 阅读 · 4 评论 -
Unix/Linux编程:非阻塞IO
在打开文件时指定O_NONBLOCK标志,目的有二如果open()调用未能立即打开文件,则返回错误,而非陷入阻塞。有一种情况属于例外,调用open()操作FIFO可能会陷入阻塞调用 open()成功后,后续的 I/O 操作也是非阻塞的。若 I/O 系统调用未能立即完成,则可能会只传输部分数据,或者系统调用失败,并返回 EAGAIN 或 EWOULDBLOCK 错误。具体返回何种错误将依赖于系统调用。Linux 系统与许多 UNIX 实现一样,将两个错误常量视为同义。管道、FIFO、套接字、设备(比转载 2021-05-23 00:08:38 · 347 阅读 · 0 评论 -
Unix/Linux编程:主线程和工作线程的分工
服务器端为了能流畅处理多个客户端连接,一般在某个线程A里面accept新的客户端连接并生成新的连接的socket fd,然后将这些新连接的socketfd给另外开的数个工作线程B1、B2、B3、B4,这些工作线程处理这些新连接上的网络IO事件(即收发数据),同时,还处理系统中的另外一些事务。这里我们将线程A称为主线程,B1、B2、B3、B4等称为工作线程。工程线程的代码框架一般如下:while(!m_bQuit){ epoll_or_select_func(); handle_io_events();转载 2022-02-06 21:31:34 · 181 阅读 · 0 评论 -
Linux C/C++编程:两种高效的并发模式
并发模式是指IO处理单元和多个逻辑单元之间协调完成任务的方法。服务器主要有两种并发编程模式:半同步/半异步 、领导者/追随者 模式半同步/半异步在IO模型中,同步和异步指的是是内核向应用程序是何种IO事件(是就绪事件还是完成事件),以及该有谁来完成IO读写(是应用程序还是内核)在并发模式中,“同步”指的是程序完全按照代码序列的顺序执行;异步指的是程序的执行需要由系统事件(比如中断、信号等)的驱动异步线程执行效率高,实时性强,但是难调试和难扩展;同步线程效率相对低,实时性差,但是逻辑简单容易编写。因转载 2021-01-04 14:44:19 · 920 阅读 · 0 评论 -
Unix/Linux编程:/etc/hosts、/etc/services文件详解
etc/hosts文件详解host文件hosts —— the static table lookup for host name(主机名查询静态表)。hosts文件是Linux系统上一个负责ip地址与域名快速解析的文件,以ascii格式保存在/etc/目录下。hosts文件包含了ip地址与主机名之间的映射,还包括主机的别名。在没有域名解析服务器的情况下,系统上的所有网络程序都通过查询该文件来解析对应于某个主机名的ip地址,否则就需要使用dns服务程序来解决。通过可以将常用的域名和ip地址映射加入转载 2021-12-14 11:55:12 · 2272 阅读 · 0 评论 -
Unix/Linux编程:IO多路复用之poll
APIpoll()执行的任务同select很相似。两者间的主要区别在于我们要如何指定待检查的文件描述符。在select中,我们提供三个集合,在每个集合中标明我们感兴趣的文件描述符。而在poll中我们提供一列文件描述符,并在每个文件描述符上标明我们感兴趣的事件NAME poll, ppoll - 监视并等待多个文件描述符的属性变化SYNOPSIS #include <poll.h> int poll(struct pollfd *fds,转载 2021-08-06 17:54:04 · 614 阅读 · 0 评论 -
Unix/Linux编程:socket编程中,如何检查数据的有效性
对端异常处理在socket编程中,我们需要一些防范对端异常的方法,比如,通过read等调用时,可以通过对EOF的判断,随时防范对端程序崩溃int nBytes = recv(connfd, buffer, sizeof(buffer), 0);if (nBytes == -1) { error(1, errno, "error read message");} else if (nBytes == 0) { error(1, 0, "client closed \n");}比如转载 2021-12-06 21:24:09 · 487 阅读 · 0 评论 -
Unix/Linux编程:怎么老是出现“地址已经被使用”
引入现象:当服务器重启之后,总是碰到“Address is use”。一个服务器例子static int count; static void sig_int(int signo) { printf("\nreceived %d datagrams\n", count); exit(0);} int main(int argc, char **argv) { int listenfd; listenfd = socket(AF_INET, SOCK_S转载 2021-12-06 20:38:17 · 1303 阅读 · 0 评论 -
Unix/Linux编程:UDP也可以是“已连接”?
从一个例子开始我们先从一个客户端例子开始,在这个例子中,客户端在 UDP 套接字上调用 connect 函数,之后将标准输入的字符串发送到服务器端,并从服务器端接收处理后的报文。当然,和服务器端发送和接收报文是通过调用函数 sendto 和 recvfrom 来完成的。#include "lib/common.h"# define MAXLINE 4096 int main(int argc, char **argv) { if (argc != 2) { e转载 2021-12-05 23:13:31 · 116 阅读 · 0 评论 -
Unix/Linux编程:如何检测连接无效,使用keep-alive还是应用心跳?
在很多情况下,连接的一段需要一直感知连接的状态,如果连接无效了,应用程序可能需要报错,或者重新发起连接等。很多刚接触TCP编程的人会惊讶的发现,在没有数据读写的“静默”的连接上,是没有办法发现TCP连接是有效的还是无效的。比如客户端突然崩溃,服务端可能在几天内都维护着一个无用的TCP连接。TCP Keep-Alive选项那有没有办法开启类似...转载 2021-12-05 21:02:19 · 296 阅读 · 0 评论 -
Unix/Linux编程:socket阻塞式读写再理解
建立连接的根本目的是为了数据的收发。拿我们常用的网络场景举例子,我们在浏览商品或者购买货品的时候,并不会感觉到网络连接的存在,但是我们可以真切感觉到数据在客户端和服务端有效的传送,比如浏览商品信息的不断刷新,购买货品时显式购买成功的消息等。首先我们来看一下发送数据发送数据发送数据时常用的有三个函数,分布是write、send、sendmsgssize_t write (int socketfd, const void *buffer, size_t size)ssize_t send (int s转载 2021-11-04 14:28:09 · 934 阅读 · 0 评论 -
Unix/Linux编程:使用epoll时需要将socket设为非阻塞吗?
结论提出这个问题说明对网络编程的一些基本原理未搞明白,先说下结论:一个socket是否设置为阻塞模式,只会影响到connect/accept/send/recv四个socket API函数,不会影响到select/poll/epoll_wait函数,后三个函数的超时或者阻塞时间是由其函数自身参数控制的原理分析下面详细的解释,为了方便解释,在这之前我们先明确几个基础概念:connfd:创建socket,主动发起连接的一端(客户端),该端调用connect函数主动发起连接listenfd:创建转载 2021-09-30 15:19:28 · 733 阅读 · 0 评论 -
Unix/Linux编程:深度理解select、poll和epoll
在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序。在大数据、高并发、集群等一些名词唱得火热之年代,select和poll的用武之地越来越有限,风头已经被epoll占尽。本文便来介绍epoll的实现机制,并附带讲解一下select和poll。通过对比其不同的实现机制,真正理解为何epoll能实现高并发。select()和poll() IO多路复用模型select的缺点单个进程能够监视的文件描述符的数量存在最大限制,通常是1转载 2021-09-28 14:42:09 · 1502 阅读 · 1 评论 -
Unix/Linux编程:Netlink机制
什么是Netlink通信机制Netlink是linux提供的用于内核和用户态进程之间的通信方式。但是注意虽然Netlink主要用于用户空间和内核空间的通信,但是也能用于用户空间的两个进程通信。只是进程间通信有其他很多方式,一般不用Netlink。除非需要用到Netlink的广播特性时。NetLink机制是一种特殊的socket,它是Linux特有的,由于传送的消息是暂存在socket接收缓存中,并不为接受者立即处理,所以netlink是一种异步通信机制。系统调用和ioctl是同步通信机制.转载 2021-09-24 11:19:32 · 3584 阅读 · 0 评论 -
Unix/Linux编程:既然有了HTTP请求,为什么还要RPC调用
回答首先HTTP和RPC并不是一个并行概念rpc是远程过程调用,其调用协议通常包含传输协议和序列化协议。传输协议包含: 如著名的 [gRPC](grpc / grpc.io) 使用的 http2 协议,也有如dubbo一类的自定义报文的tcp协议。序列化协议包含: 如基于文本编码的 xml json,也有二进制编码的 protobuf hessian等。因此我理解的你想问的问题应该是:为什么要使用自定义 tcp 协议的 rpc 做后端进程通信?要解决这个问题就应该搞清楚http使用的tcp协议和转载 2021-09-22 20:49:25 · 283 阅读 · 0 评论