socket通信之最简单的I/O 多路复用

在Linux/UNIX 下,有下面这五种I/O 操作方式:
1.阻塞 I/O
2. 非阻塞 I/O
3.I/O 多路复用
4.信号驱动 I/O(SIGIO)
5.异步 I/O

至于每种模式的含义自己去查吧,百度百科、wiki百科介绍的都很详细,要是介绍的话,我也就是抄袭过来,要学会使用搜索引擎~~

还记得上一篇文章的例子吧,那就是基于阻塞I/O模式的,简单的不能再简单的socket通信,写那篇主要是为了对socket通信有个简单的认识及明白各个函数的使用方法,以下是为更深一步做基础。

这篇要介绍下I/O多路复用,重要的函数:

1.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。

注意:关于返回值问题,若有就绪描述符则为其数目,若超时则为0,若出错则为1

2.几个重要的宏

FD_CLR(inr fd,fd_set* set);用来清除描述词组 set中相关 fd的位
FD_ISSET(int fd,fd_set *set);用来测试描述词组 set中相关 fd的位是否为真
FD_SET(int fd,fd_set*set);用来设置描述词组 set中相关 fd的位
FD_ZERO(fd_set *set);用来清除描述词组 set的全部位参数

3.一个重要的结构体
timeout为结构 timeval,用来设置 select()的等待时间,其结构定义如下:
struct timeval
{
 time_t tv_sec;
 time_t tv_usec;
};
下面是常见的程序片段
  fs_set readset;
  FD_ZERO(&readset);
  FD_SET(fd,&readset);
  select(fd+1,&readset,NULL,NULL,NULL);
  if(FD_ISSET(fd,readset){……}

完成的代码例子:

#include <stdio.h>
#include <sys/time.h>   
#include <sys/types.h>  
#include <unistd.h>     
#define TIMEOUT 5 /* select timeout in seconds *
#define BUF_LEN 1024 /* read buffer in bytes */ 
int main (void)   
{ 
	struct timeval tv;
	fd_set readfds;   
	int ret;  
	/* Wait on stdin for input. */  
	FD_ZERO(&readfds);
	FD_SET(STDIN_FILENO, &readfds); 
	/* Wait up to five seconds. */  
	tv.tv_sec = TIMEOUT;    
	tv.tv_usec = 0;   
	/* All right, now block! */     
	ret = select (STDIN_FILENO + 1,&readfds,NULL,NULL,&tv);
	if (ret == -1) 
	{  
		perror("select"); 
		return 1; 
	} 
	else if (!ret) 
	{  
		printf ("%d seconds elapsed.\n", TIMEOUT);      
		return 0; 
	} 
	/*
	* Is our file descriptor ready to read? 
	* (It must be, as it was the only fd that       
	* we provided and the call returned     
	* nonzero, but we will humor ourselves.)
	*/
	if (FD_ISSET(STDIN_FILENO, &readfds)) 
	{ 
		char buf[BUF_LEN+1];
		int len;
		/* guaranteed to not block */   
		len = read (STDIN_FILENO, buf, BUF_LEN);
		if (len == -1) 
		{  
			perror ("read");  
			return 1; 
		} 
		if (len) 
		{
			buf[len]='\0';    
			printf ("read: %s\n", buf);     
		} 
		return 0; 
	} 
	fprintf (stderr, "This should not happen!\n");  
	return 1; 
} 

代码不是很长,是一个最简单的例子,很好理解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值