poll系统调用和select类似。也是在指定时间内轮询一定数量的文件描写叙述符,以測试当中是否有就绪者。poll和select效率差点儿相同,仅仅是其使用接口相对简单些,poll不在局限于1024个文件描写叙述符。poll监听事件和触发事件分开,event表示监听事件。revents表示触发的事件。

相比select不用每一次都须要又一次设置监听事件。

 #include <poll.h>

 int poll(struct pollfd *fds, nfds_t nfds, int timeout);
//第一个參数是struct pollfd数组
struct pollfd
{
int   fd;   /* file descriptor */你要监控文件描写叙述符
     short events;   /* requested events */ 监听文件描写叙述符上的事件 传入參数由用户设置
     short revents;    /* returned events */监控文件描写叙述符事件返回值 传出參数由内核设置
}; POLLIN普通或带外优先数据可读,即POLLRDNORM | POLLRDBAND
POLLRDNORM-数据可读
POLLRDBAND-优先级带数据可读
POLLPRI 高优先级可读数据
POLLOUT普通或带外数据可写
POLLWRNORM-数据可写
POLLWRBAND-优先级带数据可写
POLLERR 错误发生
POLLHUP 发生挂起
POLLNVAL 描写叙述字不是一个打开的文件 第二个參数。指结构体数组长度。
timeout 毫秒级等待
-1:堵塞等,#define INFTIM -1 Linux中未定义此宏
0:马上返回。不堵塞进程
>0:等待指定毫秒数,如当前系统时间精度不够毫秒,向上取值

poll server端实例:

#include<stdio.h>
#include<string.h>
#include<poll.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<errno.h>
#define OPEN_MAX 1024 int create_listen(int port)
{
int listen_st,on;
struct sockaddr_in s_addr;
listen_st =socket(AF_INET,SOCK_STREAM,0);
if(listen_st==-1) {
perror("socket error ");
return -1;
}
if(setsockopt(listen_st,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))==-1)
{
perror("setsockopt error");
return -1;
}
s_addr.sin_port=htons(port);
s_addr.sin_family=AF_INET;
s_addr.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(listen_st,(struct sockaddr*)&s_addr,sizeof(struct sockaddr_in))==-1)
{
perror("bind error");
return -1;
}
if (listen(listen_st, 5) == -1) // 设置文件描写叙述符具有监听的功能
{
perror("listen error");
return -1;
}
return listen_st;
} int run_server(int port)
{
int i,maxi,listen_st,conn_st,sockaddr_len;
int nready;
struct pollfd client[OPEN_MAX];
char buf[1024];
struct sockaddr_in c_addr;
listen_st=create_listen(port);
if(listen_st==-1)
{
return -1;
}
for(i=1;i<OPEN_MAX;i++)
{
client[i].fd=-1;
}
client[0].fd=listen_st;
client[0].events=POLLIN;
maxi=0;
while(1)
{
nready = poll(client,maxi+1,-1);//poll 堵塞
if(nready<0)
{
perror("poll error");
break;
}
if((client[0].revents&POLLIN))//检測listen_st
{
sockaddr_len=sizeof(c_addr);
conn_st=accept(listen_st,(struct sockaddr *)&c_addr,&sockaddr_len);
printf("received form %s at port:%d \n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
for(i=0;i<OPEN_MAX;i++)
{
if(client[i].fd<0)
{
client[i].fd=conn_st;
client[i].events=POLLIN;
break;
}
}
if(i==OPEN_MAX)
{
printf("too many client \n");
close(conn_st);
}else
{
if(i>maxi) //记录最大下标
{
maxi=i;
}
}
if(--nready==0) continue;
} for(i=1;i<=maxi;i++)
{
if((conn_st=client[i].fd)<0)
{
continue;
} if(client[i].revents&POLLIN)
{
memset(buf,0,sizeof(buf));
int rv=read(conn_st,buf,sizeof(buf));
if(rv<0)
{
if(errno==ECONNRESET)/* 当收到RST标志时*/
//这样的错误是因为客户端发过FIN ACk掉线了客服端进程已经结束了 服务端再发FIN 客户端会发送RST
{
printf("client aborted connection \n");
close(conn_st);
client[i].fd=-1;
}
}
else if(rv==0)
{
printf("close client \n");
close(conn_st);
client[i].fd=-1;
}
else
{
printf("recv from client:%s \n",buf);
write(conn_st,buf,strlen(buf));
}
if (--nready == 0) break; //就绪个数减一
} }
}
close(listen_st);
return 0;
} int main(int argc,char *argv[])
{
if(argc<2)
{
printf("usage:%s port \n",argv[0]);
return 0;
}
int port=atoi(argv[1]);
if(port==0)
{
printf("port error \n");
return 0;
}
printf("start server \n");
run_server(port);
return 0;
}

最新文章

  1. PhpStorm提高效率的使用方法及设置
  2. Markdown:认识&amp;入门
  3. VS2015详细安装步骤
  4. SQLServer2005利用维护计划自动备份数据库
  5. SVN clean up问题
  6. [Gauss]POJ1681 Painter&#39;s Problem
  7. 忽然想到,为什么以前iOS的工资高
  8. Visual Studio项目模板与向导开发
  9. String类的方法
  10. JAVA学习知识点汇总
  11. 一文读懂阻塞、非阻塞、同步、异步IO
  12. Django Rest framework 之 序列化
  13. 在td中的输入英文为什么不自动换行???
  14. 使用systemd严格保证启动顺序
  15. Golang context包解读
  16. 环境变量篇getenv putenv setenv
  17. JavaScript引擎理解
  18. Day20-单表中获取表单数据的3种方式
  19. jquery实现表单验证简单实例
  20. 成都Uber优步司机奖励政策(4月8日)

热门文章

  1. JAVA——不简单的fianl关键字
  2. 用Go向MySQL导入.csv文件
  3. Java常用工具类---image图片处理工具类、Json工具类
  4. 5-Java-C(位平方和)
  5. CREATE GROUP - 定义一个新的用户组
  6. error while loading shared libraries: libclntsh.so.11.1
  7. mysql 使用ip地址连接不上;MySQL 可以用localhost 连接,但不能用IP连接的问题,局域网192.168.*.* 无法连接mysql
  8. Getting start with dbus in systemd (02) - How to create a private dbus-daemon
  9. jquery ajax 同步异步的执行
  10. li标签和checkbox绑定