poll()函数学习笔记(适合小白理解)

在工作中遇到了poll()函数,决定来了解一下,参考《UNIX环境高级编程》。

我的理解是:poll()函数有一个监听池,我们把要监听的文件描述符以及我们对该描述符感兴趣的条件(读,写等等)放进池子里,然后就等poll()帮我们监听,等poll()正常返回时,就是有描述符发生了变化,我们通过遍历找到这个变化的文件描述符,再去进行相应的操作(读,写等等)即可。

函数原型:

#include 
int poll(struct pollfd fdarray[], nfds_t nfds, int timeout);

返回值:

准备就绪的描述符数目;若超时,返回0;若出错,返回-1。

参数说明:

    pollfd结构如下,

struct pollfd{ 
  int fd;        /* file descriptor to check, or < 0 to ignore */
  short events;  /* events of interest on fd*/
  short revents; /* events that occurred on fd*/
  }; 

    fd是监听的文件描述符,

    events设置的值,是我们关心的每个文件描述符会发生的哪些事件

    revents的值用作返回时,说明每个文件描述符发生了哪些事件,也就是实际发生的事件

    events和revents的常用值有POLLIN,POLLRDNORM,POLLRDBAND等等,具体含义可以百度

 nfds用来指定fdarray数组中的元素数目。经过测试,如果监听了两个fd,但是nfds==1的情况下,只有fdarray[0].fd能被监听到

 timeout指定的是我们愿意等待多长时间。timeout==-1,永远等待;timeout==0,不等待;timeout>0,等待timeout毫秒。

实例:

说明:由于前几天刚看了socket本地进程间通信,所以就在此基础上进行poll()的使用。

我们知道,默认情况下,TCP下的accept和UDP下的recvfrom都是阻塞型,直到有client给其发送数据才会返回。我们可以在accept或者recvfrom之前调用poll来帮我们监听,等监听的文件描述符有变化了再去accept或者recvfrom。

本例子用socket本地进程间通信,基于UDP的。server端一共打开了两个本地socket文件描述符,将其加入poll监听池中,设置timeout为-1,即永久等待。然后client端分别向两个文件描述符发送数据,看看server端会有什么样的输出。下面给出代码。

#include 	
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
#include
#include

/*****************Server****************/ 

#define MAX_BUFFER_SIZE 1024
#define IN_FILES 2
 
int main(int argc ,char **argv)
{
	struct pollfd fds[IN_FILES];
	char buf[MAX_BUFFER_SIZE] = "", domain[32] = "";
	int i;
	int ret;
	int server_sockfd[IN_FILES];
	int server_len[IN_FILES];
	struct sockaddr_un server_address[IN_FILES];
	
	for(i=0; i
#include
#include
#include
#include
#include
#include
#include 

/*****************Client****************/

int main(int argc, char **argv)
{
	int fd, ret, len;
	struct sockaddr_un un;
	char str[24] ;
	memset(str, 0, sizeof(str));
	strcpy(str, "Hello World!");

	//create socket
	fd = socket(AF_UNIX, SOCK_DGRAM, 0);
	if(fd<0)
	{
		printf("socket error\n");
		return -1;
	}

	//name the socket
	un.sun_family=AF_UNIX;
	strcpy(un.sun_path, argv[1]);
	len = sizeof(un);

	ret = sendto(fd, str, strlen(str)+1, 0, (struct sockaddr*)&un, sizeof(struct sockaddr_un));
	printf("ret = %d, errno = %d, %s\n", ret, errno, strerror(errno));
	return 0;
}

gcc poll.c -o poll

gcc udp_client.c -o udp_client

演示:

用client往udp_tmp0发送字符串:

用client往udp_tmp1发送字符串: 

 

好了,就到这里,由于我也才看了一点点poll,也没测试它的很多用法,所以理解很浅显,欢迎大家交流。 

你可能感兴趣的:(poll()函数学习笔记(适合小白理解))