多路复用之select

该博客介绍了如何使用select函数来监控文件描述符,包括其参数含义、功能、宏定义以及一个读取操作的代码示例。通过select,可以判断哪些描述符可读、可写或存在异常,并能设置超时时间。在遇到错误或超时时,提供了相应的处理策略。
摘要由CSDN通过智能技术生成

头文件

#include <sys/select.h>

函数原型

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)

函数作用:监控指定描述符集合中哪些描述符可不可以做相应的操作(读/写)或是否有异常。

函数参数:
① nfds:最大的描述符+1。给select指定关心描述符的最大范围。
② readfds:是否有数据可读。
③ writefds:是否有数据可写。
④ exceptfds:是否存在异常。
⑤ timeout:超时时间。如果没有描述符可读、可写、有异常。则select函数将阻塞指定的时间长度。
为NULL:一直阻塞到有描述符可操作。
不为NULL,为0:select成为非阻塞函数。
不为NULL,不为0:select阻塞指定的时间长度。

函数返回值:
大于0:可读、可写或有异常的描述符总数
等于0:指定的阻塞时间到了
小于0:select有错误发生。其中信号引起的错误应该被忽略

select相关宏

select使用描述字集,典型地是一个整数数组

void FD_ZERO (fd_set *fdset); // 将变量的所有位初始化为0
void FD_SET (int fd,fd_set *fdset); // 在fdset中注册fd的信息
void FD_CLR (int fd,fd_set *fdset); // 在fdset中清除fd的信息
intFD_ISSET(int fd,fd_set *fdset); // 若fdset中包含fd的信息,则返回真

代码示例

//循环的进行读操作
while(1)
{
	char sbuf[2048];
	int iRet = 0;
	int fd;
	fd_set fdset;
	struct timeval szTimeval;	//超时时间
	szTimeval.tv_sec = 0;		//0秒
	szTimeval.tv_usec = 500;	//500微秒
	FD_ZERO(&fdset);
	FD_SET(fd, &fdset);
	iRet = select(fd+1, &fdset, NULL, NULL, &szTimeval);
	if(iRet > 0 && FD_ISSET(fd, &fdset))
	{
		iRet2 = recv(fd, sbuf, 2048, 0);
		if(iRet2 > 0)
		{
			//对读到的数据进行处理
		}
		else
		{
			if((errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN))
			{
				continue;	//忽略信号引起的错误
			}
			else
			{
				//接收数据出错
				perror("recv");
				break;
			}
		}
	}
	else if(iRet == 0)
	{
		//超时
		continue;
	}
	else
	{
		if((errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN))
		{
			continue;	//忽略信号引起的错误
		}
		else
		{
			//select真正出错
			perror("http post select");
			break;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈海平20220310

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值