代码纯享:Linux下epoll实现回射服务器

5 篇文章 0 订阅
2 篇文章 0 订阅

简介,使用epoll和socket在Linux系统里实现一个简单的回射服务器,客户端发什么内容,服务器端就回客户端什么内容。

​
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <poll.h>
#include <sys/epoll.h>
#define PORT 8000
#define FWQIP 0  //可改为自己IP
int main(int argc, char* argv[])
{
    int lfd=socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in seraddr,cliaddr;
    seraddr.sin_family=AF_INET;
    seraddr.sin_port=htons(PORT);
    seraddr.sin_addr.s_addr=FWQIP;
    int a=bind(lfd,(struct sockaddr*)&seraddr,sizeof(seraddr));
    if(a<0)
    {
        perror("bind error:");
        return 0;
    }
    listen(lfd,64);
    socklen_t len=sizeof(cliaddr);
    
    //创建一个epoll对象
    int epfd = epoll_create(64);
    //结构体表示这个文件描述的监听事件,和如何识别他(data域)
    struct epoll_event event;
    event.events = EPOLLIN;
    event.data.fd = lfd;

    //把lfd放到红黑树里面
    epoll_ctl(epfd, EPOLL_CTL_ADD, lfd, &event);

    //epoll_wait需要一个结构体来保存返回的触发事件,创建结构体。
    struct epoll_event events[1024];

    int i;//循环因子
    while(1)
    {
        int epollret = epoll_wait(epfd, events, 1024, -1);//返回触发的事件,-1表示非阻塞
        if(epollret < 0)
        {
            perror("epoll_wait  error:");
            exit(1);
        }
        else//epoll_wait没有出错,则需要对返回来的events数组进行处理
        {
            for(i=0; i < epollret; i++)
            {
                if(events[i].events & EPOLLIN)//事件触发
                {
                    int pfd = events[i].data.fd;
                    if(pfd == lfd)//表示lfd事件触发,有新的客户端请求连接
                    {
                        int  cfd=accept(lfd,(struct sockaddr*)&cliaddr,&len);
                        if(cfd < 0)
                        {
                            perror("accept error:");
                            exit(1);
                        }
                        int cliport=ntohs(cliaddr.sin_port);//网络端口号转本地端口号
                        char det[1025];
                        inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, det,sizeof(det));//网络IP转本地IP
                        printf("客户端已连接 IP = %s 端口号 = %d\n", det, cliport);

                        //把cfd加入到红黑树中
                        event.events = EPOLLIN;//还是监听读事件
                        event.data.fd = cfd;
                        epoll_ctl(epfd, EPOLL_CTL_ADD, cfd, &event);//添加到红黑树
                    }
                    else//不是lfd则做回射
                    {
                        char buf[1024];
                       int rr = read(pfd, buf, sizeof(buf));
                       if(rr < 0)
                       {
                            perror("read error:");
                            exit(1);
                       }
                       else if(rr == 0)
                       {
                            printf("客户端已断开\n");
                            epoll_ctl(epfd, EPOLL_CTL_DEL, pfd, NULL);//删除文件描述符。
                       }
                       else
                       {
                           write(1, buf, rr);
                           write(pfd, buf, rr);
                       }
                    }
                }
            }
        }
    }
    return 0;
}

​

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值