当前位置: 首页 > news >正文

山东企业建站系统信息七牛 wordpress缩略图

山东企业建站系统信息,七牛 wordpress缩略图,哪个购物平台正品,怎么做营销在阅读本篇博客之前#xff0c;建议大家先去看一下我之前写的这篇博客#xff0c;否则你很可能会一头雾水 【Linux】多路IO复用技术①——select详解如何使用select模型在本地主机实现简易的一对多服务器#xff08;附图解与代码实现#xff09;http://t.csdnimg.cn/…在阅读本篇博客之前建议大家先去看一下我之前写的这篇博客否则你很可能会一头雾水 【Linux】多路IO复用技术①——select详解如何使用select模型在本地主机实现简易的一对多服务器附图解与代码实现http://t.csdnimg.cn/kPjvk 如果你看完了上面这篇博客或者对select的原理和网络通信方面有一定了解的话就可以开始阅读下面的内容了。那么废话不多说我们正式开始了。 目录 poll模型的优缺点 poll模型的相关接口 监听结构体struct pollfd 监听函数poll poll函数使用时的注意事项 本地主机使用poll模型实现简易一对多服务器的程序实现 程序构成        结果图示 这篇博客为大家讲解的是多路IO复用技术②——poll PS:由于poll模型的原理和select模型的实现原理基本一致并且select的原理已经在上述的博客中详细讲过所以这里不再浪费篇幅再讲一遍了 首先我们先来了解一下poll模型的优缺点 poll模型的优缺点 优点 在内网场景下poll也算是不错的IO复用模式对监听集合进行了传入传出分离设置不需要用户再自己设置传入集合监听集合和传出集合就绪集合相比selectpoll可以监听的事件种类更加丰富具体可见下面的博客接口部分——struct pollfd可以为不同的套接字设置不同的监听事件不像select模型只能批量设置监听事件poll模型可以监听的socket数量不受1024的硬限制允许用户自定义数组作为监听集合数组想设置多大就设置多大其实这也不能完全算优点下面讲缺点时会讲为什么 缺点 poll模型的兼容性极差甚至部分linux系统都不认识poll模型更别说windows系统了随着select的持续使用会产生大量的拷贝开销和挂载开销原因和select模型一样与select模型一样poll的监听也是通过一次次的遍历实现的非常消耗CPU会导致服务器吞吐能力会非常差。更可怕的是select遍历的大小仅为1024而poll模型遍历的大小是由用户决定的如果用户设置的监听集合大小为100000就意味着poll遍历的大小就是100000服务器很可能会直接瘫痪 在了解了poll模型的优缺点后我们来了解一下poll模型的相关函数 poll模型的相关接口 以下接口的头文件都是 #include poll.h 监听结构体struct pollfd 先来介绍一下poll模型中的监听集合是什么样的 poll中的监听集合是一个结构体数组这里我们将变量名设为listen_array[size]写法如下所示 #define SIZE 10000struct pollfd listen_array[SIZE];//用户自定义的监听集合pollfd结构体中的成员 struct pollfd {int fd; //目标套接字的文件描述符取消监听就设为-1short events; //想要监听什么事件short revetns; }; 我们来讲解一下revents这个成员的作用 当套接字就绪时触发某相关事件时系统会将其设置为对应事件的宏定义用户可以使用该成员判断套接字是否就绪 比如套接字中有数据来了需要读取处理触发读事件系统就会自动将revents设置为读事件对应的常量POLLIN用户就可以去通过判断revents是不是等于POLLIN来判断是否读事件就绪 events 和 revents 可取的值及对应事件如下图所示 监听函数poll 先来介绍一下一会会用到的参数 #define SIZE 10000; //监听集合的大小struct pollfd listen_array[SIZE]; //自定义监听集合nfds_t nfds; //最大监听套接字的数量一般传监听数组的大小int timeout; //工作模式 我们来介绍一下这个timeouttimeout有以下几种设置方式 timeout -1poll 调用后阻塞等待直到被监视的某个文件描述符上的某个事件就绪。timeout 0poll 调用后非阻塞等待无论被监视的文件描述符上的事件是否就绪poll 检测后都会立即返回。timeout 特定的时间值poll 调用后在指定的时间内进行阻塞等待如果被监视的文件描述符上一直没有事件就绪则在经过长度为timeout的时间后 poll 进行超时返回。以毫秒为级别 函数功能返回值int poll(listen_array , nfds , timeout);监听集合中是否有套接字就绪 1.函数调用成功则返回就绪的套接字个数 2.如果 timeout 时间耗尽但没有套接字就绪则返回 0。 3.如果函数调用失败则返回 -1同时会传出错误码。 常见的错误码有以下四种 EFAULT数组listen_array不包含在调用程序的地址空间中。EINTR此调用被信号所中断。EINVALnfds值的大小超过RLIMIT_NOFILE。ENOMEM核心内存不足。 poll函数使用时的注意事项 既然前面都说了poll模型可以监听的socket数量不受1024的硬限制允许用户自定义数组作为监听集合数组想设置多大就设置多大 那我现在写一段小代码大家看一看这个程序对不对系统会不会报错假设已经完成了网络初始化并已经设置了服务器套接字监听 int ready_num;//阻塞监听socket相关事件 if((ready_num poll(client_sockfd_array , 4096 , -1)) -1) {perror(poll call failed\n);exit(0); } else {printf(1\n); } 怎么样有自己的结果了吗接下来我们公布正确答案 这个程序是错的 为什么呢这就要牵涉到进程相关的知识了 这是因为一个进程默认打开的最大文件描述符个数就是1024我们可以通过ulimit -a命令在终端下查看如下图所示 所以当我们在poll函数中的最大监听数那个位置填入比1024更大的数值的话系统就会报错警告Invalid argument——无效的参数 想要填入比1024更大的数值我们就需要去修改默认的文件描述符数量由于每个系统甚至每个版本改动文件描述符数量的操作方式不一定一样所以永久修改文件描述符数量的方式这里就不多作介绍了感兴趣的同学可以去查一下对应自己系统、对应自己版本的修改方式 我们这里简单介绍一下只对当前终端生效的修改方式如下图所示 使用poll模型实现简易一对多服务器的程序实现 程序构成 该服务器与客户端由以下几个程序共同组成 func_2th_parcel.h定义二次包裹的函数名func_2th_parcel.c对网络初始化相关的函数进行二次包裹poll_server.c使用poll模型的服务器程序client.c客户端程序 /************************************************************************* File Name: func_2th_parcel.h Author: Nan Mail: **qq.com Created Time: 2023年10月18日 星期三 18时32分22秒************************************************************************/#include stdio.h #include stdlib.h #include unistd.h #include string.h #include sys/types.h #include sys/wait.h #include sys/stat.h #include signal.h #include pthread.h #include fcntl.h #include arpa/inet.h #include netdb.h #include sys/mman.h #include time.h #include ctype.h #include sys/select.h #include sys/socket.h #include poll.h #include sys/epoll.h//socket函数的二次包裹 int SOCKET(int domain , int type , int protocol);//bind函数的二次包裹 int BIND(int sockfd , const struct sockaddr* addr , socklen_t addrlen);//listen函数的二次包裹 int LISTEN(int sockfd , int backlog);//send函数的二次包裹 ssize_t SEND(int sockfd , const void* buf , size_t len , int flags);//recv函数的二次包裹 ssize_t RECV(int sockfd , void* buf , size_t len , int flags);//connect函数的二次包裹 int CONNECT(int sockfd , const struct sockaddr* addr , socklen_t addrlen);//accept函数的二次包裹 int ACCEPT(int sockfd , struct sockaddr* addr , socklen_t addrlen);//网络初始化函数 int SOCKET_NET_CREATE(const char* ip , int port);//服务端与客户端建立连接并返回客户端套接字文件描述符 int SERVER_ACCEPTING(int server_fd); /************************************************************************* File Name: func_2th_parcel.c Author: Nan Mail: **qq.com Created Time: 2023年10月18日 星期三 18时32分42秒************************************************************************/#include func_2th_parcel.hint SOCKET(int domain , int type , int protocol){int return_value;if((return_value socket(domain , type , protocol)) -1){perror(socket call failed!\n);return return_value;}return return_value; }int BIND(int sockfd , const struct sockaddr* addr , socklen_t addrlen){int return_value; if((return_value bind(sockfd , addr , addrlen)) -1){perror(bind call failed!\n);return return_value;} return return_value; }int LISTEN(int sockfd , int backlog){int return_value; if((return_value listen(sockfd , backlog)) -1){perror(listen call failed!\n);return return_value;} return return_value; }ssize_t SEND(int sockfd , const void* buf , size_t len , int flags){ssize_t return_value;if((return_value send(sockfd , buf , len , flags)) -1){perror(send call failed!\n);return return_value;}return return_value; }ssize_t RECV(int sockfd , void* buf , size_t len , int flags){ssize_t return_value; if((return_value recv(sockfd , buf , len , flags)) -1){perror(recv call failed!\n);return return_value;} return return_value; }int CONNECT(int sockfd , const struct sockaddr* addr , socklen_t addrlen){int return_value; if((return_value connect(sockfd , addr , addrlen)) -1){perror(connect call failed!\n);return return_value;} return return_value; }int ACCEPT(int sockfd , struct sockaddr* addr , socklen_t addrlen){int return_value; if((return_value accept(sockfd , addr , addrlen)) -1){perror(accept call failed!\n);return return_value;} return return_value; }int SOCKET_NET_CREATE(const char* ip , int port){int sockfd;struct sockaddr_in addr;addr.sin_family AF_INET;addr.sin_port htons(port);inet_pton(AF_INET , ip , addr.sin_addr.s_addr);sockfd SOCKET(AF_INET , SOCK_STREAM , 0);BIND(sockfd , (struct sockaddr*)addr , sizeof(addr));LISTEN(sockfd , 128);return sockfd; }int SERVER_ACCEPTING(int server_fd) {int client_sockfd;struct sockaddr_in client_addr;char client_ip[16];char buffer[1500];bzero(buffer , sizeof(buffer));bzero(client_addr , sizeof(client_addr));socklen_t addrlen sizeof(client_addr);client_sockfd ACCEPT(server_fd , (struct sockaddr*)client_addr , addrlen);bzero(client_ip , 16);//将客户端的IP地址转成CPU可以识别的序列并存储到client_ip数组中inet_ntop(AF_INET , client_addr.sin_addr.s_addr , client_ip , 16);sprintf(buffer , Hi , %s welcome tcp test server service..\n , client_ip);printf(client %s , %d , connection success , client sockfd is %d\n , client_ip , ntohs(client_addr.sin_port) , client_sockfd);SEND(client_sockfd , buffer , strlen(buffer) , MSG_NOSIGNAL);return client_sockfd; } /************************************************************************* File Name: poll_server.c Author: Nan Mail: **qq.com Created Time: 2023年10月25日 星期三 18时53分30秒************************************************************************/#include func_2th_parcel.hint main(void) {//一、进行网络初始化int server_sockfd;//服务器套接字文件描述符struct pollfd client_sockfd_array[1024];//存放客户端套接字相关结构体的数组 int client_sockfd;//客户端套接字文件描述符int ready_num;//获取处于就绪状态的套接字数目char rw_buffer[1500];//读写缓冲区int flag;int recv_len;//客户端发来的数据长度//将结构体数组中对应套接字文件描述符的那一位置为-1方便后面查找就绪套接字for(int i 1 ; i 1024 ; i){//从1开始初始化是因为0那一位要留给服务器套接字client_sockfd_array[i].fd -1;client_sockfd_array[i].events POLLIN;//都设置为监听读事件}bzero(rw_buffer , sizeof(rw_buffer));server_sockfd SOCKET_NET_CREATE(192.168.79.128 , 6060);//初始化服务器套接字网络信息结构体//将服务器套接字结构体初始化一下client_sockfd_array[0].fd server_sockfd;client_sockfd_array[0].events POLLIN;printf(poll_server wait TCP connect\n);//二、启动监听等待socket相关事件while(1){//阻塞等待socket读相关事件if((ready_num poll(client_sockfd_array , 1024 , -1)) -1){perror(poll call failed\n);exit(0);}//printf(readynum %d\n , ready_num);while(ready_num){//辨别就绪如果是服务端套接字就绪if(client_sockfd_array[0].revents POLLIN){client_sockfd SERVER_ACCEPTING(client_sockfd_array[0].fd);//与客户端建立TCP链接for(int i 1 ; i 1024 ; i){//将该客户端套接字放到数组中有空缺的地方if(client_sockfd_array[i].fd -1){client_sockfd_array[i].fd client_sockfd;break;}}client_sockfd_array[0].revents 0;//清0防止ready_num 1时会多次误判断就绪套接字为服务器套接字}//如果是客户端套接字就绪else{for(int i 1 ; i 1024 ; i){//检测数组中下标位为i的地方是否存放的有客户端套接字文件描述符if(client_sockfd_array[i].fd ! -1){//如果存放的有客户端套接字文件描述符且该套接字处于就绪状态if(client_sockfd_array[i].revents POLLIN){recv_len RECV(client_sockfd_array[i].fd , rw_buffer , sizeof(rw_buffer) , 0);//获取数据长度printf(客户端%d 发来数据 : %s , 现在进行处理\n , client_sockfd_array[i].fd , rw_buffer);flag 0;//如果recv_len 0,就说明与客户端套接字对应的客户端退出了将对应客户端套接字移出监听集合if(recv_len 0){printf(客户端%d 已下线\n , client_sockfd_array[i].fd);close(client_sockfd_array[i].fd);client_sockfd_array[i].fd -1;break;}//如果recv_len 0说明需要进行业务处理小写字母转大写字母while(recv_len flag){rw_buffer[flag] toupper(rw_buffer[flag]);flag;}printf(已向客户端%d 发送处理后的数据 : %s\n , client_sockfd_array[i].fd , rw_buffer);SEND(client_sockfd_array[i].fd , rw_buffer , recv_len , MSG_NOSIGNAL);//发送处理后的数据给客户端bzero(rw_buffer , sizeof(rw_buffer));//清空读写缓冲区recv_len 0;//重置数据长度client_sockfd_array[i].revents 0;//清0防止ready_num 1时会多次误判断就绪套接字为该客户端套接字break;}}}}ready_num--;//已经处理一个就绪套接字数量-1}}close(server_sockfd);printf(server shutdown\n);return 0; } /************************************************************************* File Name: client.c Author: Nan Mail: **qq.com Created Time: 2023年10月19日 星期四 18时29分12秒************************************************************************/#include stdio.h #include stdlib.h #include unistd.h #include string.h #include sys/types.h #include sys/wait.h #include sys/stat.h #include signal.h #include pthread.h #include fcntl.h #include sys/socket.h #include netdb.h #include arpa/inet.h #include time.h//服务器实现大小写转换业务int main() {//1.定义网络信息结构体与读写缓冲区并初始化struct sockaddr_in dest_addr;char buffer[1500];bzero(dest_addr , sizeof(dest_addr));bzero(buffer , sizeof(buffer));dest_addr.sin_family AF_INET;dest_addr.sin_port htons(6060);//字符串ip转大端序列inet_pton(AF_INET , 192.168.79.128 , dest_addr.sin_addr.s_addr);int sockfd socket(AF_INET , SOCK_STREAM , 0);int i;//2.判断连接是否成功if((connect(sockfd , (struct sockaddr*) dest_addr , sizeof(dest_addr))) -1){perror(connect failed!\n);exit(0);}recv(sockfd , buffer , sizeof(buffer) , 0);printf(%s , buffer);bzero(buffer , sizeof(buffer));//3.循环读取终端输入的数据while( (fgets(buffer , sizeof(buffer) , stdin) ) ! NULL){i strlen(buffer);buffer[i-1] \0;//向服务端发送消息send(sockfd , buffer , strlen(buffer) , MSG_NOSIGNAL);//接收服务端发来的消息recv(sockfd , buffer , sizeof(buffer) , 0);//打印服务端发来的信息printf(response : %s\n , buffer);//清空读写缓冲区以便下一次放入数据bzero(buffer , sizeof(buffer));}//4.关闭套接字断开连接close(sockfd);return 0; } 结果图示 以上就是本篇博客的全部内容了大家有什么地方没有看懂的话可以在评论区留言给我咱要力所能及的话就帮大家解答解答 今天的学习记录到此结束啦咱们下篇文章见ByeBye
http://www.hkea.cn/news/14406705/

相关文章:

  • 商城网站建设都有哪些类型安徽省建设厅到底哪个网站
  • 济南网站优化推广互联网保险新规
  • 网站宣传的手段有哪些广州制作app
  • 衡阳网站优化外包首选漯河北京网站建设公司
  • flash网站在线diy源码首页网站怎么做
  • 如何做请求队列防止网站高并发大沥网站设计
  • 响应式网站用什么工具网页免费下载
  • 个人网站备案能做什么内容北京装饰公司排行 2019
  • 做网站需要怎么分工常德网站建设哪家权威
  • 健身网站模板旅游网站怎样做宣传
  • 网站空间邮箱网络架构和现实架构的差异
  • html5特效网站wordpress导出pdf
  • 软件技术是什么优化网站做内链接
  • 个人网站介绍六灶网站建设
  • 做资源教程网站五星级酒店网站建设方案
  • 新网站如何做百度收录外贸网站平台seo推广
  • 网站seo链接购买爱站工具包的主要功能
  • 国外网站怎么建设seo应该如何做
  • 网站内容维护合同建筑外观设计网站
  • 网上做效果图网站有哪些软件有哪些广告设计与制作专业需要美术功底吗
  • 口碑好的免费网站建设专业做礼品团购的网站
  • 做网站分几步wordpress demo data
  • 电商网站前台模块网站开发的书
  • 即墨有做网站的吗湖南网站建设有限公司
  • 南京微信网站开发wordpress功能 更改
  • 网级移动营销免费下载优化大师
  • 做鞋子皮革有什么网站wordpress调用文章的tags
  • 焦作网站建设哪家专业自贡企业网站建设公司
  • 高端网站设计推广v信haotg8旅游网站界面设计
  • 永嘉县住房和城乡规划建设局网站公司网页制作培训试题