c/c++

select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET

假装没事ソ 提交于 2021-02-18 04:02:03
select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型,原型: #include <sys/time.h> #include <unistd.h> int select(int maxfd,fd_set *rdset,fd_set *wrset,fd_set *exset,struct timeval *timeout); 参数maxfd是需要监视的最大的文件描述符值+1;rdset,wrset,exset分别对应于需要检测的可读文件描述符的集合,可写文件描述符的集 合及异常文件描述符的集合。struct timeval结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值为0。 fd_set(它比较重要所以先介绍一下)是一组文件描述字(fd)的集合,它用一位来表示一个fd(下面会仔细介绍),对于fd_set类型通过下面四个宏来操作: FD_ZERO(fd_set *fdset);将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在系统分配内存空间后,通常并不作清空处理,所以结果是不可知的。 FD_SET(int fd, fd_set *fdset);用于在文件描述符集合中增加一个新的文件描述符。 FD_CLR(int fd, fd

【网络编程】域名解析

妖精的绣舞 提交于 2020-11-16 01:50:46
项目中有这种场景:C/S通过RPC方式通信。服务端提供一个域名(如:www.xxx.xxx.com),客户端每次请求需要将该域名转换成相应的IP,然后才可以发起请求。这里做一个小小的总结。 #include <stdio.h> #include <unistd.h> #include <netdb.h> #include <arpa/inet.h> #include <errno.h> int main(int argc, char *argv[]) { // 域名解析 char host_name[256] = "www.test.xxx.xxx.com"; // xxx应替换成实际域名 struct hostent *hptr; hptr = gethostbyname(host_name); if(NULL == hptr) { perror("dsn error"); exit(1); } char ip[256] = {0,}; if(NULL == inet_ntop(hptr->h_addrtype, hptr->h_addr, ip, sizeof(ip))) // 项目中一般是这个,首选IP { perror("inet_ntop error."); exit(1); } printf("ip:%s\n", ip); return 0; } 编译并运行: gcc

C到C++ 快速过度 C 结构体到类

|▌冷眼眸甩不掉的悲伤 提交于 2020-11-10 08:32:25
<!--结构体--> 还记得C语言中的结构体么? struct Point{ double x; double y; }; 上面的代码是一个“结构体模版”,我们利用它创建了一个叫做Point的类型。 在这之后,我们就可以像声明基本类型的变量一样声明Point类型: Point ob; ob叫做结构体Point的一个“实例”。(更多被称为“对象”,下文中不再区分“实例”和“对象”这两个词。) 而当我们 int n; 的时候,会讲声明了int类型的一个“变量” n。 而当我们Point ob; 的时候,我们一般称“构建了Point的一个对象” ob。 结构体是一种复合类型,但是它和同样身为复合类型的数组不同。 数组是相同类型元素的线性集合,而一个结构体中却能含有不同类型的成员。 <!--数组操作技巧--> // 这是穿插的关于数组常用操作的讲解 和结构体与类并没有多大关系 不感兴趣的可以跳过^_^ char name[20]; 我们这样就声明了一个数组,并且每个name[i](0 <=i < 20)都是一个独立的char类型的变量。它们被称为数组的“元素”。 值得一提的是,同一个数组的各个元素所占用的内存空间是连续的。 这使得我们在遍历(检索)整个数组的时候,速度非常的快: int line[] = {2, 5, 6, 7, 8, 12, -5, -32}; // 1 int len

Linux下DIR,dirent,stat等结构体详解

旧巷老猫 提交于 2020-04-24 23:35:26
Linux下DIR,dirent,stat等结构体详解 最近在看Linux下文件操作相关章节,遇到了这么几个结构体,被搞的晕乎乎的,今日有空,仔细研究了一下,受益匪浅。 首先说说DIR这一结构体,以下为DIR结构体的定义: 1.struct __dirstream 2. { 3. void *__fd; 4. char *__data; 5. int __entry_data; 6. char *__ptr; 7. int __entry_ptr; 8. size_t __allocation; 9. size_t __size; 10. __libc_lock_define (, __lock) 11. }; 12. 13.typedef struct __dirstream DIR; DIR结构体类似于FILE,是一个内部结构,以下几个函数用这个内部结构保存当前正在被读取的目录的有关信息(摘自 《UNIX环境高级编程(第二版)》 )。函数 DIR *opendir(const char *pathname),即打开文件目录,返回的就是指向DIR结构体的指针,而该指针由以下几个函数使用: 1.struct dirent *readdir(DIR *dp); 2. 3.void rewinddir(DIR *dp); 4. 5.int closedir(DIR *dp);

【翻译】gSOAP 2.8.5 用户手册(待续)

爷,独闯天下 提交于 2020-04-23 14:49:15
gSOAP 2.8.5 用户手册 1 简介 gSOAP工具基于编译器技术为C/C++提供自动的SOAP和XML数据绑定。(这句话不好理解,且向下看)。该工具使用自动生成代码以及先进的映射方法,简化了基于C/C++的SOAP/XML Web service和XML应用程序的开发。(有点靠谱了,可以理解成该工具可以帮助程序员完成协议底层的代码)。大多数Web services工具采用以WSDL/SOAP为中心的观点,并且提供一组API,使用这些API必须使用相应的类库来处理特定XML数据结构。这强迫用户去适应该程序逻辑才能使用这些类库,因为用户在使用该特定厂商的API时必须编写代码去填充XML和抽取XML数据。这往往导致一个脆弱的解决方案,几乎没有数据一致性、类型安全和XML验证的保证。(好了,损完别人了,下面开始自夸)。与其他工具不同的是,gSOAP使用编译器技术为用户隐藏了WSDL、SOAP、特定XML的实现细节,同时自动提供XML有效性验证、内存管理和类型安全序列化,从而提供透明的解决方案。gSOAP工具可将原有的数据类型和用户自定义的数据类型映射成等价的XML数据类型,反之亦然。因此,通过一个简单的API得到了完美的SOAP互操作性,从而可使用用户从WSDL/SOAP/XML的细节中解脱出来,集中精力处理应用程序逻辑。(主要还是讲了gSOAP可以给用户,即程序员,提供协议透明

编程珠玑:向量旋转(旋转交换)

大兔子大兔子 提交于 2020-03-19 13:04:16
3 月,跳不动了?>>> 问题描述 请将一个具有n个元素的一维向量向左旋转i个位置。例如,假设n=8,i=3,那么向量abcdefgh旋转之后得到向量defghabc。简单编码使用一个具有n个元素的中间向量分n步即可完成此作业。你可以仅使用几十字节的微小内存,花费与n成比例的时间来旋转该向量吗? 解决思路 方案一: 将向量x中的前i个元素复制到一个临时数组中,接着将余下的n-i个元素左移i个位置,然后再将前i个元素从临时数组中复制回x中的后面位置。 该方案使用了i个额外的位置,如i足够大,过于浪费空间。 方案二: 定义一个函数来将x向左旋转一个位置,然后调用该函数i次。 该方案需要将数组移到i将,过于浪费时间。 方案三: 先将x[0]移临时变量t中,然后将x[i]移到x[0]中,x[2i]移到x[i]中,依次类推,直到我们又回到从x[0]中提取元素,不过在这时我们要从t中提取元素,然后结束该过程。当i=3,n=12时,该阶段将以下面的次序移到各个元素。 如果该过程不能移动所有的元素,那么我们再从x[1]开始移动,一直依次进行下去,直到移动了所有的元素时为止。 该方案过于精巧,像书中所说的一样堪称巧妙的杂技表演,非常容易出错。 方案四: 旋转向量x实际上就是将向量ab的两个部分交换为向量ba,这里a代表x的前i个元素。假设a比b短。将b分割成b l 和b r ,使b r

C Primer Plus 第7章 C控制语句:分支和跳转 7.1 if语句

独自空忆成欢 提交于 2020-03-02 19:06:31
这个程序读入一系列每日的最低温度(摄氏度),并报告输入的总数,以及最低温度在零度以下的天数的百分率。在一个循环里使用scanf()读入数值,在每一次循环中增加计数器的值来统计输入数值的个数。if语句检测低于零度以下的温度并单独统计这些天的数目。 程序清单7.1 colddays.c ------------------------------------ //colddays.c --求出温度低于零度的天数的百分率 #include <stdio.h> int main (void) { const int FREEZING = 0; float temperature; int cold_days = 0; int all_days = 0; printf("Enter the list of daily low temperatures.\n"); printf("Use Celsius,and enter q to quit.\n"); while(scanf("%f",&temperature)==1) { all_days++; if(temperature<FREEZING) cold_days++; } if(all_days!=0) printf("%d days total:%.1f%% were below freezing.\n", all_days,100

C Primer Plus 第7章 C控制语句:分支和跳转 7.2 if语句中添加 else 关键字

夙愿已清 提交于 2020-03-02 19:06:17
if else 语句的通用形式为: if (expression) statement1 else statement2 如果expression为真(非零),就执行statement1;如果expression为假或零,则执行跟在else后的那一条语句(statement2)。 如果希望在if和else之间有多条语句,必须使用花括号创建一个代码块。 if语句使您能够选择是否执行某个动作。if else语句使您可以在两个动作之间进行选择。 7.2.1 另一个例子:介绍getchar()和putchar() 现在我们将接触专门 为面向字符I/O而设计的一对C函数:getchar()和putchar()。 getchar()函数没有参数, 它返回来自输入设备的下一个字符。 ch=getchar();与scanf("%c",&ch);有同样的效果。 putchar()函数打印它的参数。 例如,下面的语句将先前赋值给ch的值作为字符打印出来: putchar(ch); 该语句与printf("%c",ch);有同样的效果。 因为这些函数仅仅处理字符,所以它们比更通用的scanf()和printf()函数更快而且更简洁。同样,注意到 它们不需要格式说明符,因为它们只对字符 起作用。 这两个函数通常 都是在stdio.h文件中定义的。 下面的示例将说明这些函数是如何工作的,“如果字符 是空格

C Primer Plus 第7章 C控制语句:分支和跳转 7.3获得逻辑性

耗尽温柔 提交于 2020-03-02 18:40:44
假设需要编写一个程序,用来计算在一个输入的句子中,除单引号和双引号以外的字符出现了多少次。可以用逻辑运算符来实现该目的,可以用英文的句号来标识一个句子的结束。 程序清单 7.6 chcount.c #include #define PERIOD '.' int main (void) { int ch; int charcount=0; while((ch=getchar())!=PERIOD) { if(ch!='"' && ch!='\'') //如果字符不是双引号并且它不是单引号 charcount++; } printf("There are %d non-quote characters.\n",charcount); return 0; } 逻辑运算符的优先级低于关系运算符 ,所以不必使用圆括号组合表达式。 C的逻辑运算符 运算符 含义 && 与 || 或 ! 非 假设A和B是两个简单的关系表达式,那么可以声明如下: *仅当A和B都为真时,A&&B才为真。 *如果A为真或B为真或二者都为真,A||B为真。 *如果A为真,!A为假;如果A为假,!A为真。 7.3.1 改变拼写法:iso646.h C99标准为逻辑运算符增加了可供选择的拼写法。它们在iso646.h头文件中定义。 表7.4 逻辑运算符的可选表示法 传统的 iso646.h && and || or !

#define 中的“ # 运算符”和“ ## 运算符”

隐身守侯 提交于 2020-03-02 08:02:58
1. 利用宏参数创建字符串:# 运算符 在类函数宏(function-like macro)的替换部分中,“#”符号用作一个预处理运算符,它可以把语言符号(token)转化为字符串。例如,如果 x 是一个宏参量,那么 #x 可以把参数名转化为相应的字符串。该过程称为 字符串化 。 说明:类函数宏就是带参数的宏。类函数宏的定义中,用圆括号括起来一个或多个参数,随后这些参数出现在替换部分。 #include <stdio.h> #define PSQR(x) printf("The square of " #x " is %d. /r/n", (x) * (x)) int main( void ) { int y = 5; PSQR(y); PSQR(2 + 4); return 0; } // 输出: The square of y is 25. // 用 "y" 代替 #x The square of 2 + 4 is 36. // 用 "2 + 4" 代替 #x #define STRING2(x) #x #define STRING(x) STRING2(x) #define WQ wangqi #pragma message(STRING2(WQ)) // WQ(字符串) #pragma message(STRING(WQ)) // wangqi(字符串) 2.