当前位置: 首页> 科技> 能源 > 设计制作费税率_运营是做什么的工作_百度广告代理商_百度收录查询入口

设计制作费税率_运营是做什么的工作_百度广告代理商_百度收录查询入口

时间:2025/7/19 21:07:52来源:https://blog.csdn.net/zhangzhangkeji/article/details/143374558 浏览次数:0次
设计制作费税率_运营是做什么的工作_百度广告代理商_百度收录查询入口

(1)书里提出了疑问,epoll 函数的工作方式,区分为水平触发与边缘触发 :

在这里插入图片描述

(2) 11 1 5-5 伊圣雨老师的 epoll 教学范例:回声客户端代码与错误处理函数 error_handling () :

在这里插入图片描述

++ 源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define BUF_SIZE   100void error_handling(char * str)//此函具有换行功能
{   // int fputs(const char *str,FILE *stream);fputs(str,stderr); // fputs()写入字符串到文件中fputc('\n',stderr);//     但不会主动添加换行符。exit(1); // int fputc(int char,FILE *stream);
}int main(int argc,char * argv[])
{   // 回声客户端,三个参数,argc = 3int  sock, str_len;    char message[BUF_SIZE];struct sockaddr_in  serv_adr;if(argc != 3) { printf("参数不是3个\n");exit(1); }sock = socket(PF_INET,SOCK_STREAM,0);if(sock == -1)error_handling("创建套接字socket() 失败\n");memset(&serv_adr,0,sizeof(serv_adr));serv_adr.sin_family = AF_INET;// serv_adr.sin_addr.s_addr = inet_addr(argv[1]);// inet_addr() 的语义不明,不好// 处理文本地址,只需使用 inet_pton() 与 inet_ntop() 即可。// int inet_pton(int af, const char *src, void *dst);inet_pton(AF_INET, argv[1], &serv_adr.sin_addr.s_addr);serv_adr.sin_port = htons(atoi(argv[2]));if(connect(sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr)) == -1)error_handling("connect() 失败");elseputs("客户端套接字连接至服务器成功\n");while(1) // 函 fputs() 不会自动添加换行符{   // int fputs(const char *str,FILE *stream);fputs("Input message(Q to quit):", stdout);fgets(message, BUF_SIZE, stdin);// char *fgets(char *str, int n, FILE *stream);// 函 fgets 会保留换行符在字符串中。可手动去除if( !strcmp(message,"Q\n") || !strcmp(message,"q\n") )break;write(sock, message, strlen(message));str_len = read(sock, message, BUF_SIZE - 1);message[str_len] = 0; // read()不会主动添加空字符。printf("服务器端回响过来的信息:%s",message);}close(sock);return 0;}

(3) 11 2 5-5 伊圣雨老师的 epoll 教学范例:回声服务器端代码:使用 epoll ,大缓存,水平触发:

在这里插入图片描述

++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>#define BUF_SIZE   100
#define EPOLL_SIZE  50void error_handling(char * str)//此函具有换行功能
{   // int fputs(const char *str,FILE *stream);fputs(str,stderr);fputc('\n',stderr);// int fputc(int char,FILE *stream);exit(1);
}int main(int argc,char * argv[])
{   // 最基本版本的 epoll() 实现的回声服务器端,argc = 2int serv_sock, clnt_sock, str_len, i, epfd, event_cnt;struct sockaddr_in serv_adr,clnt_adr;socklen_t adr_sz;    char buf[BUF_SIZE]; // 100struct epoll_event event, * ep_events;if(argc != 2) { printf("参数不是2个\n");exit(1); }serv_sock = socket(PF_INET,SOCK_STREAM,0);memset(&serv_adr,0,sizeof(serv_adr));serv_adr.sin_family = AF_INET; // 协议serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址serv_adr.sin_port = htons(atoi(argv[1])); //端口号if(bind(serv_sock,(struct sockaddr *)&serv_adr, sizeof(serv_adr))==-1)error_handling("bind() error"); // 不必再处理字符串换行问题if(listen(serv_sock,5)==-1)    // 绑定,开启监听error_handling("listen() error");epfd = epoll_create(EPOLL_SIZE); // EPOLL_SIZE = 50event.events  = EPOLLIN;event.data.fd = serv_sock;epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);ep_events = malloc(sizeof(struct epoll_event) * EPOLL_SIZE);while (1) // 此循环在正常情况下是不会退出的。{   event_cnt = epoll_wait(epfd, ep_events, EPOLL_SIZE, -1);       if(-1 == event_cnt) { // 防止少写 ==puts("epoll_wait() 出错"); // 结束循环,进程退出break; //puts() 会自动换行}for(i = 0 ; i < event_cnt ; i++){   if(ep_events[i].data.fd == serv_sock)//监听套接字{   adr_sz = sizeof(clnt_adr);clnt_sock = accept(serv_sock,(struct sockaddr *)&clnt_adr,&adr_sz);event.events  = EPOLLIN;event.data.fd = clnt_sock;epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event); printf("创建了通信套接字 id: %d\n", clnt_sock);} else {   // read() 是不会为接收的字符串添加空字符 '\0' 的str_len = read(ep_events[i].data.fd, buf, BUF_SIZE);if(0 == str_len) // FIN 报文{   epoll_ctl(epfd, EPOLL_CTL_DEL,ep_events[i].data.fd,NULL);close(ep_events[i].data.fd);printf("关闭了通信套接字 id: %d\n",ep_events[i].data.fd);}else   write(ep_events[i].data.fd, buf, str_len);}} // for(...)  } // while(...)close(serv_sock); // 如此,监听套接字 close(epfd); //serv_sock 会被关闭两次。return 0;}

++ 11 3 5-5 伊圣雨老师的 epoll 教学范例:图 2 的回声服务器的测试效果 :

在这里插入图片描述

(4) 11 4 5-5 伊圣雨老师的 epoll 教学范例:回声服务器端代码:使用 epoll ,小缓存,验证默认的水平触发模式:

在这里插入图片描述

++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>#define BUF_SIZE     3 
#define EPOLL_SIZE  50void error_handling(char * str)//此函具有换行功能
{   // int fputs(const char *str,FILE *stream);fputs(str,stderr);fputc('\n',stderr);// int fputc(int char,FILE *stream);exit(1);
}int main(int argc,char * argv[])
{   //验证 epoll 的默认的水平触发模式的回声服务器端,argc = 2int serv_sock, clnt_sock, str_len, i, epfd, event_cnt;struct sockaddr_in serv_adr,clnt_adr;socklen_t adr_sz;    char buf[BUF_SIZE]; // 100struct epoll_event event, * ep_events;if(argc != 2) { printf("参数不是2个\n");exit(1); }serv_sock = socket(PF_INET,SOCK_STREAM,0);memset(&serv_adr,0,sizeof(serv_adr));serv_adr.sin_family = AF_INET; // 协议serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址serv_adr.sin_port = htons(atoi(argv[1])); //端口号if(bind(serv_sock,(struct sockaddr *)&serv_adr, sizeof(serv_adr))==-1)error_handling("bind() error"); // 不必再处理字符串换行问题if(listen(serv_sock,5)==-1)    // 绑定,开启监听error_handling("listen() error");epfd = epoll_create(EPOLL_SIZE); // EPOLL_SIZE = 50event.events  = EPOLLIN;event.data.fd = serv_sock;epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);ep_events = malloc(sizeof(struct epoll_event) * EPOLL_SIZE);while (1) // 此循环在正常情况下是不会退出的。{   event_cnt = epoll_wait(epfd, ep_events, EPOLL_SIZE, -1);       if(-1 == event_cnt) { // 防止少写 ==puts("epoll_wait() 出错"); // 结束循环,进程退出break; //puts() 会自动换行} //增加 puts() 行统计 epoll_wait() 的返回次数,其余部分不变。puts("从 epoll_wait() 返回了");for(i = 0 ; i < event_cnt ; i++){   if(ep_events[i].data.fd == serv_sock)//监听套接字{   adr_sz = sizeof(clnt_adr);clnt_sock = accept(serv_sock,(struct sockaddr *)&clnt_adr,&adr_sz);event.events  = EPOLLIN;event.data.fd = clnt_sock;epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event); printf("创建了通信套接字 id: %d\n", clnt_sock);} else {   // read() 是不会为接收的字符串添加空字符 '\0' 的str_len = read(ep_events[i].data.fd, buf, BUF_SIZE);if(0 == str_len) // FIN 报文{   epoll_ctl(epfd, EPOLL_CTL_DEL,ep_events[i].data.fd,NULL);close(ep_events[i].data.fd);printf("关闭了通信套接字 id: %d\n",ep_events[i].data.fd);} else   write(ep_events[i].data.fd, buf, str_len);}} // for(...)  } // while(...)close(serv_sock); // 如此,监听套接字 close(epfd); //serv_sock 会被关闭两次。return 0;}

++ 11 5 5-5 伊圣雨老师的 epoll 教学范例:图 4 的回声服务器的默认水平触发模式的测试效果:

在这里插入图片描述

(5) 11 6 5-5 伊圣雨老师的 epoll 教学范例:回声服务器端代码:使用 epoll ,小缓存,通信套接字使用非阻塞的边缘触发模式:

在这里插入图片描述

++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <fcntl.h> //增加这俩头文件
#include <errno.h>#define BUF_SIZE     3 
#define EPOLL_SIZE  50void error_handling(char * str)//此函具有换行功能
{   // int fputs(const char *str,FILE *stream);fputs(str,stderr);fputc('\n',stderr);// int fputc(int char,FILE *stream);exit(1);
}void setnonblockingmode(int fd) //非阻塞
{   int flag = fcntl(fd, F_GETFL, 0);fcntl(fd, F_SETFL, flag | O_NONBLOCK); }int main(int argc,char * argv[])
{   //验证 epoll 的边缘触发模式的回声服务器端,argc = 2int serv_sock, clnt_sock, str_len, i, epfd, event_cnt;struct sockaddr_in serv_adr,clnt_adr;socklen_t adr_sz;    char buf[BUF_SIZE]; // 100struct epoll_event event, * ep_events;if(argc != 2) { printf("参数不是2个\n");exit(1); }serv_sock = socket(PF_INET,SOCK_STREAM,0);setnonblockingmode(serv_sock);//设置监听套接字为非阻塞memset(&serv_adr,0,sizeof(serv_adr));serv_adr.sin_family = AF_INET; // 协议serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址serv_adr.sin_port = htons(atoi(argv[1])); //端口号if(bind(serv_sock,(struct sockaddr *)&serv_adr, sizeof(serv_adr))==-1)error_handling("bind() error"); // 不必再处理字符串换行问题if(listen(serv_sock,5)==-1)    // 绑定,开启监听error_handling("listen() error");epfd = epoll_create(EPOLL_SIZE); // EPOLL_SIZE = 50event.events  = EPOLLIN; // 监听套接字仍为水平触发模式event.data.fd = serv_sock;epoll_ctl(epfd, EPOLL_CTL_ADD, serv_sock, &event);ep_events = malloc(sizeof(struct epoll_event) * EPOLL_SIZE);while (1) // 此循环在正常情况下是不会退出的。{   event_cnt = epoll_wait(epfd, ep_events, EPOLL_SIZE, -1);       if(-1 == event_cnt) { // 防止少写 ==puts("epoll_wait() 出错"); // 结束循环,进程退出break;  //puts() 会自动换行 }       puts("从 epoll_wait() 返回了");//统计epoll_wait()的返回次数for(i = 0 ; i < event_cnt ; i++) //依次处理所有发生了事件的套接字{   if(ep_events[i].data.fd == serv_sock)//监听套接字{   adr_sz = sizeof(clnt_adr);clnt_sock = accept(serv_sock,(struct sockaddr *)&clnt_adr,&adr_sz);setnonblockingmode(clnt_sock);event.events  = EPOLLIN | EPOLLET; //通信套接字边缘触发event.data.fd = clnt_sock;epoll_ctl(epfd, EPOLL_CTL_ADD, clnt_sock, &event); printf("创建了通信套接字 id: %d\n", clnt_sock);} else while(1) {   // 从通信套接字读取所有数据str_len = read(ep_events[i].data.fd, buf, BUF_SIZE);if(0 == str_len) // FIN 报文{   epoll_ctl(epfd, EPOLL_CTL_DEL,ep_events[i].data.fd,NULL);close(ep_events[i].data.fd);printf("关闭了通信套接字 id: %d\n",ep_events[i].data.fd);break;  // 下面的是读完了接收缓存中的数据,返回-1,并设置errno} else if(str_len < 0){ if(EAGAIN == errno) break; } //跳出内循环else   write(ep_events[i].data.fd, buf, str_len);} //内层 while(...)} // for(...)  } // while(...)close(serv_sock); // 如此,监听套接字 close(epfd); //serv_sock 会被关闭两次。return 0;}

++11 7 5-5 伊圣雨老师的 epoll 教学范例:图 6 的回声服务器的非阻塞边缘触发模式的测试效果:

在这里插入图片描述

(6)

谢谢

关键字:设计制作费税率_运营是做什么的工作_百度广告代理商_百度收录查询入口

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: