Unix网络编程之poll函数实现服务器反射客户端-server.c

来源:互联网 发布:电视直播软件安装包 编辑:程序博客网 时间:2024/05/20 21:43

1.poll 函数:

int poll(struct pollfd *fds,nfds_t nfds,int timeout);

       其中第一个参数表示struct pollfd 结构体的数组,struct pollfd 的结构体如下:

struct pollfd{      int fd;      short events;      short revents;}
        第二个参数表示最大描述符的个数加一。第三个参数表示超时限制规定的时间。


代码:


#include "unp.h"#define FD_MAXSIZE 1024#include<poll.h>int main(void){        int listenfd,connfd,nready;        if((listenfd = socket(AF_INET,SOCK_STREAM,0))<0)                ERR_EXIT("socket");        struct sockaddr_in cliaddr,servaddr;        memset(&servaddr,0,sizeof(servaddr));        servaddr.sin_family = AF_INET;        servaddr.sin_port = htons(45678);        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);        if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)                ERR_EXIT("bind");        listen(listenfd,SOMAXCONN);        int on = 1;        if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)                ERR_EXIT("setsockopt");        struct pollfd client[FD_MAXSIZE];        int i =0;        for(i = 0;i<FD_MAXSIZE;i++){           client[i].fd = -1;        }        int maxi = 0;        int maxfd = listenfd;        char recvbuf[1024];        client[0].fd = listenfd;              //我们把0号位用来监听是否有客户端过来。        client[0].events = POLLIN;            //我们关心的是写入操作。因此我们需要把events位置设置成POLLIN。        int num = 0;        while(1){                memset(recvbuf,0,sizeof(recvbuf));                nready = poll(client,maxfd+1,-1);      //将第三个参数设置成-1 , 也就是一直阻塞下去,直到poll函数有可读事件发生。                if(client[0].revents & POLLIN){          //如果监听套接字的描述符有可读事件。                        socklen_t len = sizeof(cliaddr);                        connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&len);  //accept                        struct sockaddr_in peeraddr;                        socklen_t lens = sizeof(struct sockaddr_in);                        getpeername(connfd,(struct sockaddr*)&peeraddr,&lens);                        printf("ip = %s , port = %d \n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));  //打印对方的地址和端口。                        for(i = 0;i<FD_MAXSIZE;i++){                                if(client[i].fd == -1){                                        client[i].fd = connfd;                                        client[i].events = POLLIN;         //遍历一遍pollfd数组(不需要遍历完),找到第一个,并设置成POLLIN                                        printf("%d \n",++num);                                        if(i > maxi)                                                maxi = i;                                        break;                                }                        }                        if(i == FD_MAXSIZE){                                printf("too many clients\n");                        }                }                for(i = 1;i<= maxi;i++){                              //遍历一遍pollfd 数组(到maxi),看看哪个数组成员发生了可读事件。                        if(client[i].fd == -1)                                continue;                        int con = client[i].fd;                        if(client[i].revents & POLLIN){            //发生了可读事件。                                int ret = readline(con,recvbuf,sizeof(recvbuf));                                if(ret < 0)                                        ERR_EXIT("readn");                                else if(ret == 0){                                        client[i].fd =-1; close(con);                                        continue;                                }                                printf(recvbuf,stdout);                                writen(con,recvbuf,ret);                        }                }        }        return 0;}



0 0