C-socket编-poll()模型

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>
#include <errno.h>
#include <ctype.h>

#include "wrap.h"

#define MAXLINE 80
#define SERV_PORT 8000
#define OPEN_MAX 1024

int main()
{
        int i,j,maxi,listenfd,connfd,sockfd;
        int nready;     /* 接收poll的返回值,记录满足监听事件的fd个数 */
        ssize_t n;
        char buf[MAXLINE], str[INET_ADDRSTRLEN];
        socklen_t clielen;
        struct pollfd client[OPEN_MAX];
        struct sockaddr_in clieaddr, servaddr;

        listenfd=Socket(AF_INET, SOCK_STREAM, 0);

        int opt=1;
        setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
        servaddr.sin_port = htons(SERV_PORT);

        Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

        Listen(listenfd,128);

        client[0].fd=listenfd;  /* 要监听的第一个文件描述符 存入client[0] */
        client[0].events=POLLIN;        /* listenfd监听普通读事件 */

        for(i=1;i<OPEN_MAX;i++);        /* 用-1初始化client[]里剩下的元素 */
                client[i].fd=-1;


        maxi=0; /* maxi 保存有效元素的最大下标  */

        for(;;)
        {
                nready=poll(client,maxi+1,-1);  /*阻塞监听是否有客户端连接请求*/
                if(client[0].revents & POLLIN)
                {
                        clielen=sizeof(clieaddr);
                        connfd=Accept(listenfd, (struct sockaddr *)&clieaddr, &clielen);
                        printf("received from %s at port %d \n",
                        inet_ntop(AF_INET, &clieaddr.sin_addr,str,sizeof(str)),
                        ntohs(clieaddr.sin_port));

                        for(i=1;i<OPEN_MAX;i++)
                        {
                                if(client[i].fd < 0)
                                {
                                        client[i].fd=connfd;
                                        break;
                                }
                        }
                        if(i==OPEN_MAX)
                                perr_exit("too many clients");
                        client[i].events = POLLIN;
                        if(i > maxi)
                                maxi=i;
                        printf("nready=%d\n",nready);
                        if(--nready==0)
                                continue;
                        printf("nready=%d\n",nready);
                }
                for(i=1;i<=maxi;i++)
                {
                        if((sockfd=client[i].fd) <0)
                                continue;
                        if(client[i].revents & POLLIN)
                        {
                                if((n=read(sockfd, buf, MAXLINE)) <0)
                                {
                                        if(errno== ECONNRESET)
                                        {
                                                printf("client[%d] aborted connection\n",i);
                                                close(sockfd);
                                                client[i].fd=-1;
                                        }
                                        else
                                                perr_exit("read error");
                                }
                                else if(n == 0)
                                {
                                        printf("client[%d] closed connection \n",i);
                                        close(sockfd);
                                        client[i].fd=-1;
                                }
                                else
                                {
                                        for(j=0; j< n; j++)
                                                buf[j]=toupper(buf[j]);
                                        sleep(2);
                                        write(sockfd,buf,n);
                                }
                                if(--nready == 0)
                                        break;
                        }
                }
        }
        close(listenfd);
        return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值