您的位置:首页 > 其它

I/O非阻塞函数实践:poll

2014-06-04 15:38 169 查看
接上一篇文章,以poll函数实现并发请求。通过上一篇的测试我们可知,select函数无法处理大约5k以上的并发请求。且效率不高,需要每次循环对select的监听句柄重新赋值才行,轮询的赋值费时费力。因此我们以poll函数来替代select。相比于select,poll函数不需要每次重新对监听的句柄赋值,同时理论上来说,函数本身对于所支持的监听句柄数没有限制。

同样先贴上改进代码。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/poll.h>
#define MAX_CONN 100
#define MAX_NU 10000
int main(int argc, char const *argv[])
{
int count = 0;
fd_set fds;
int maxfdp;
int fd;
int yes = 1;
int i;
struct sockaddr_in servaddr;
int nfds;
//int timeout = 10000;

fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0){
perror("[Error]Create socket");
exit(1);
}
printf("Socket success!\n");

if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
perror("[Error]setsockopt");
exit(1);
}

memset(&servaddr, '\0', sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(12345);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
perror("[Error]Bind socket");
exit(1);
}
printf("Bind success!\n");

if (listen(fd, MAX_CONN) < 0){
perror("[Error]Listen socket");
exit(1);
}
printf("Listen success!\n");

struct pollfd clientfd[MAX_NU];
for (int i = 0; i < MAX_NU; ++i)
clientfd[i].fd = -1;
nfds = 1;//此处为结构体数量而非最大值
clientfd[0].fd = fd;
clientfd[0].events = POLLIN;

while(1){
switch(poll(clientfd, nfds, 0)){
case -1:
perror("[Error]Poll");
exit(1);
case 0:
//printf("Nothing\n");
break;
default:
//此处fd仅为监听套接词,如果为真则说明有连接请求
if (clientfd[0].revents & POLLIN)
{
struct sockaddr_in cltaddr;
int accept_fd;
socklen_t length = sizeof(cltaddr);
if((accept_fd = accept(fd, (struct sockaddr*)&cltaddr, &length)) < 0){
perror("[Error]Accept socket");
exit(1);
}
count++;
nfds++;
clientfd[count].fd = accept_fd;
clientfd[count].events = POLLIN;
printf("recv connect ip=%s port=%d\n", inet_ntoa(cltaddr.sin_addr), ntohs(cltaddr.sin_port));
printf("count = %d\n", count);
if (count == MAX_NU)
{
perror("[Error]Too many clients");
exit(1);
}
}
//此处不管已连接的套接词是否有数据,所以只判断监听套接词是否有数据变动
}//end switch
}//end while

return 0;
}//end main



测试了一下在这种条件下1w个请求没问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  socket poll