套接字编程---多路IO转接---epoll实现代码

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <ctype.h>

//服务器监听端口号
#define PORT 20000

//服务器监听IP
#define IP "127.0.0.1"

//服务器支持的最大连接数
#define MAX_CONNECTION 1024

//用户区字符缓存区大小
#define BUFFSIZE 1024

int main()
{
        int listenfd,connfd,sockfd,epfd;//文件描述符

        struct sockaddr_in servaddr,clieaddr;//网络地址结构体

        socklen_t clieaddr_len=sizeof(clieaddr);//存放客户端地址大小

        int ret;//临时变量

        struct epoll_event rdevt;//epoll事件

        struct epoll_event evts[MAX_CONNECTION];//epoll事件数组,用作epoll_wait的输出

        int nready;//用作epoll_wait的返回值

        int i,j;//循环因子

        char buff[BUFFSIZE],clientip[32];

        int num;

        listenfd=socket(PF_INET,SOCK_STREAM,0);//创建tcp套接字

        if(listenfd<0)
        {
                perror("socket error");
                exit(1);
        }

        //初始化服务器网络地址结构体,用作bind的参数
        memset(&servaddr,'\0',sizeof(servaddr));
        servaddr.sin_family=AF_INET;
        servaddr.sin_port=htons(PORT);
        inet_pton(AF_INET,IP,&servaddr.sin_addr);

        ret=bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr));//将listenfd赋予地址和端口

        if(ret<0)
        {
                perror("bind error");
                exit(1);
        }

        ret=listen(listenfd,128);//设置服务器为监听状态

        if(ret<0)
        {
                perror("listen error");
                exit(1);
        }

        epfd=epoll_create(MAX_CONNECTION);//创建epoll实例,并返回对应的文件描述符

        if(epfd<0)
        {
                perror("epoll_create error");
                exit(1);
        }

        //将listenfd赋值给epoll事件
        rdevt.events=EPOLLIN;
        rdevt.data.fd=listenfd;

        //将listenfd添加到epfd中进行监听
        ret=epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&rdevt);

        if(ret<0)
        {
                perror("epoll_ctl error");
                exit(1);
        }

        while(1)
        {
                nready=epoll_wait(epfd,evts,MAX_CONNECTION,-1);//开启监听

                for(i=0;i<nready;i++)
                {
                        if((sockfd=evts[i].data.fd)==listenfd)//有新的连接
                        {
                                memset(&clieaddr,'\0',sizeof(clieaddr));
                                connfd=accept(listenfd,(struct sockaddr *)&clieaddr,&clieaddr_len);

                                printf("An new connection was accepted. IP = %s, PORT = %d\n",
                                        inet_ntop(AF_INET,&clieaddr.sin_addr,clientip,sizeof(clientip)),
                                        ntohs(clieaddr.sin_port));

                                rdevt.events=EPOLLIN;
                                rdevt.data.fd=connfd;

                                ret=epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&rdevt);//将新的连接添加到epfd中进行状态监听

                                if(ret<0)
                                {
                                        perror("epoll_ctl error");
                                        close(connfd);
                                }

                                continue;
                        }

                        num=recv(sockfd,buff,sizeof(buff),0);//读取socket缓存区中的数据

                        if(num<0)
                        {
                                printf("recv error.\n");
                        } else if(num==0)
                        {
                                printf("some client had closed.\n");
                                close(sockfd);
                        }else
                        {
                                for(j=0;j<num;j++)
                                {
                                        buff[j]=toupper(buff[j]);
                                }

                                send(sockfd,buff,num,0);
                        }

                }
        }
}

运行效果:

[zlf@rhel5 day20181226]$ ./epollserver
An new connection was accepted. IP = 127.0.0.1, PORT = 33790
An new connection was accepted. IP = 127.0.0.1, PORT = 33791
An new connection was accepted. IP = 127.0.0.1, PORT = 33792
some client had closed.
some client had closed.
An new connection was accepted. IP = 127.0.0.1, PORT = 33793
An new connection was accepted. IP = 127.0.0.1, PORT = 33794
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

历史五千年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值