linux 多路复用

多路复用的概念: 在我们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);				
			}							
		}	
	}	
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值