赞
踩
多路复用的概念: 在我们linux函数接口里面有很多函数都是带阻塞功能的,例如是:read/write/accept…
阻塞函数,这些函数都是当到达某个条件的时候才会阻塞,例如read函数,当网络没有数据的时候回读会阻塞
例如:write写函数当管道写满的时候他又会阻塞。。。。。
遇到这里阻塞的问题我们之前都是,开线程去处理他,这样会造成资源的浪费。
多路复用的接口函数:
/* According to POSIX.1-2001, POSIX.1-2008 */
#include <sys/select.h>
/* According to earlier standards */ #include <sys/time.h> #include <sys/types.h> #include <unistd.h> //多路复用的设置函数 int select(int nfds, // 所有监控的文件描述符中最大的那一个加1 fd_set *readfds,// 需要监视的读集合,所有要读的文件文件描述符的集合 fd_set *writefds,// 需要监视的写集合,所有要的写文件文件描述符的集合 fd_set *exceptfds,//其他要向我们通知的文件描述符 ->一般为NULL struct timeval timeout*);//超时设置. 设置他监视的 时长 //时间结构体 struct timeval { long tv_sec; /* seconds */ long tv_usec; /* microseconds */ }; 返回值:成功:返回文件描述 (返回 1) 超时:返回0 失败:返回-1 void FD_CLR(int fd, fd_set *set);//将FD从fd_set 删除 int FD_ISSET(int fd, fd_set *set); //判断fd是否在fd_set集合中 void FD_SET(int fd, fd_set *set);// 将FD加到fd_set集合里面中 void FD_ZERO(fd_set *set); //清空fd_set集合
#include <stdio.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include <string.h> int main() { //1.创建TCP通信对象 int socketfd=socket(AF_INET,SOCK_STREAM,0); if(socketfd < 0) { perror("creat sock fail\n"); return -1; } //2.链接服务器 struct sockaddr_in seraddr={0}; seraddr.sin_family = AF_INET; //指定网络协议为 IPV4 seraddr.sin_port = htons(12580); //取值范围 最大值65535 16位的整形 1024以后 seraddr.sin_addr.s_addr = inet_addr("10.8.6.108"); //自动检测IP地址 int ret=connect(socketfd,(struct sockaddr *)&seraddr,sizeof(seraddr)); if(ret != 0) { perror("connect fail\n"); return -1; } else { printf("connect ok\n"); } //开启集合的监视 //定义一个文件描述符集合 fd_set fds; //定义一个时间结构体 struct timeval time; //循环监视文件描述符集合 while(1) { //清空文件描述符集合 FD_ZERO(&fds); //把标准输入设备加入到集合中 FD_SET(0,&fds); //把网络通信文件描述符加入到集合中 FD_SET(socketfd,&fds); //设置监视的时长 time.tv_sec = 5; time.tv_usec = 0; int ret=select(socketfd+1,&fds,NULL,NULL,&time); if(ret < 0)//错误 { perror("select fail:"); return -1; } else if(ret == 0) //超时 { printf("timeout\n"); } else if(ret > 0) //有活跃的 { printf("ret=%d\n",ret); //判断是否 标准输入设备活跃 假设是则发送数据 if(FD_ISSET(0,&fds)) { char buf[1024]={0}; read(0,buf,1024); //发送到网络中 write(socketfd,buf,strlen(buf)); } //判断是否有数据录入 if(FD_ISSET(socketfd,&fds)) { char buf[1024]={0}; read(socketfd,buf,1024); printf("getdate=%s\n",buf); } } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。