多路复用技术Linux下poll模型代码实现

多路复用技术Linux下poll模型代码实现

头文件wrap是对socketAPI的封装 点击查看

#include "wrap.h"
#include <poll.h>
#include <ctype.h>
#include <fcntl.h>

//委托监控最大值
#define MAXPFD 1024

int main()
{
		//变量定义
        int lfd, cfd, nready, maxi, n, i, sockfd, flags;
        char buf[1024];
        fd_set readfds, tempfds;
        struct pollfd client[MAXPFD];
		
		//创建SOCKET、设置端口复用、绑定端口、监听
        lfd = tcp4BindListen(9791, NULL, 128);

		//委托监控监听文件描述符的读事件
        maxi = 0;
        client[0].fd = lfd;
        client[0].events = POLLIN;

		//将还未委托的文件描述符初始化为-1
        for(i = 1; i < 1024; i++)
        {
                client[i].fd = -1;
        }

        while(1)
        {
                nready = poll(client, maxi + 1, -1);
                if(nready < 0)
                {
                        if(errno == EINTR)//被信号中断
                        {
                                continue;
                        }
                        break;
                }

                //有客户端请求连接
                if(client[0].revents == POLLIN)
                {
                        cfd = Accept(lfd, NULL, NULL);
						
						//选择一个数组下标最小且未被使用的结构体存放通信文件描述符
                        for(i = 1; i < MAXPFD; i++)
                        {
                                if(client[i].fd == -1)
                                {
                           				//委托监控读事件
                                        client[i].fd = cfd;
                                        client[i].events = POLLIN;
                                        
										//设置通信文件描述符为非阻塞
                                        flags = fcntl(cfd, F_GETFL, 0);
                                        flags = flags | O_NONBLOCK;
                                        fcntl(cfd, F_SETFL, flags);
                                        
                                        break;
                                }
                        }
						
						//如果数组最大坐标已被占用,拒绝连接请求
                        if(i == MAXPFD)
                        {
                                close(cfd);
                                printf("拒绝连接请求\n");
                        }
                        else
                        {
                                printf("连接成功\n");
                                if(maxi < i)
                                {
                                        maxi = i;
                                }
                        }
			
						//如果可读事件-1为0,跳出当前循环
                        if(--nready == 0)
                        {
                                continue;
                        }
                }

                //有客户端发送数据
                for(i = 1; i <= maxi; i++)
                {
                        //client数组中fd已关闭
                        if(client[i].fd == -1)
                        {
                                continue;
                        }

                        sockfd = client[i].fd;
                        if(client[i].revents == POLLIN)
                        {
                                while(1)
                                {
                                        bzero(buf, sizeof(buf));
                                        n = Read(sockfd, buf, sizeof(buf));

										//如果客户断开连接
                                        if(n == 0)
                                        {
                                                printf("客户断开连接\n");
                                                close(sockfd);
                                                client[i].fd = -1;
                                                if(client[i].fd == maxi)
                                                {
                                                        maxi -= 1;
                                                }

                                                break;
                                        }
                                        //如果数据读取完毕
                                        else if(n < 0)
                                        {
                                                printf("数据接受完毕\n");
                                                break;
                                        }
                                        //如果还有可读数据
                                        else
                                        {
                                                printf("读取数据 %s", buf);

                                    			/*
                                    			核心操作
												*/
                                        }
										
										//如果可读事件-1为0,跳出for循环
                                        if(--nready == 0)
                                        {
                                                break;
                                        }
                                }
                        }

                }

        }

		//关闭通信文件描述符
        close(lfd);
        return 0;
}
~                                                                                                                                                   ```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值