白皓军 2021-06-11 09:10 采纳率: 0%
浏览 6

linux服务端广播回射

服务端具有群发、回射功能

采用epoll方式、多客户端进行操作

  • 写回答

1条回答 默认 最新

  • ╰つ栺尖篴夢ゞ iOS领域优质创作者 2023-02-03 10:39
    关注

    可以参考一下:

    #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;
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥30 win from 窗口最大最小化,控件放大缩小,闪烁问题
  • ¥20 易康econgnition精度验证
  • ¥15 msix packaging tool打包问题
  • ¥28 微信小程序开发页面布局没问题,真机调试的时候页面布局就乱了
  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致