首页 > 其他分享 >UDP使用Epoll 实现

UDP使用Epoll 实现

时间:2024-07-23 16:18:41浏览次数:8  
标签:UDP listenfd addr Epoll 实现 epoll serveraddr include define

 

 

 

#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h> 
#include <errno.h> 
#include <stdlib.h>
#include <string.h>
#include <strings.h>

#define MAXLINE 10
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 5566
#define INFTIM 1000 
#define MAX_EVENT 1000

void setnonblocking(int sock)
{
    int opts;
    opts=fcntl(sock,F_GETFL);

    if(opts<0)

    {
        perror("fcntl(sock,GETFL)");
        exit(1);
    }

    opts = opts|O_NONBLOCK;
    if(fcntl(sock,F_SETFL,opts)<0)
    {
        perror("fcntl(sock,SETFL,opts)");
        exit(1);
    }    

}



int main()
{
    int i, maxi, listenfd, connfd, sockfd,epfd,nfds;
    int ret;
    ssize_t n;
    char line[MAXLINE];
    socklen_t clilen;
    char szAddr[256]="\0";

    //声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件

    struct epoll_event ev,events[20];

    //生成用epoll专用文件描述符

    epfd=epoll_create(256);printf("epoll_create(256) return %d\n", epfd);
    struct sockaddr_in clientaddr;  
    struct sockaddr_in serveraddr;  
    listenfd = socket(AF_INET, SOCK_DGRAM, 0);
    socklen_t addrlen = sizeof(clientaddr);

    //把socket设置为非阻塞方式   
    setnonblocking(listenfd);   
   //fcntl(listenfd, F_SETFL, fcntl(gUdpRecvFB[i].recv_socket, F_GETFD, 0) | O_NONBLOCK); //设置与要处理的事件相关的文件描述符 ev.data.fd=listenfd; //设置要处理的事件类型 ev.events=EPOLLIN|EPOLLET; //注册epoll事件 ret=epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev); printf("epoll_ctl return %d\n",ret); bzero(&serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; char *local_addr="127.0.0.1"; inet_aton(local_addr,&(serveraddr.sin_addr)); serveraddr.sin_addr.s_addr=inet_addr(local_addr); serveraddr.sin_port=htons(SERV_PORT); bind(listenfd,(struct sockaddr *)&serveraddr, sizeof(serveraddr)); memset(line,0,MAXLINE); for ( ; ; ) { //等待epoll事件的发生 //nfds=epoll_wait(epfd,events,MAX_EVENT,-1); nfds=epoll_wait(epfd,events,MAX_EVENT,0); //处理所发生的所有事件 for(i=0;i<nfds;++i) { if(events[i].events&EPOLLIN) { if ( (sockfd = events[i].data.fd) < 0) continue; if ((n = recvfrom(sockfd, line, MAXLINE,0,(sockaddr*)&clientaddr,&addrlen)) < 0) { if (errno == ECONNRESET) { close(sockfd); events[i].data.fd = -1; } else printf("readline error\n"); } else if (n == 0) { perror("connfd=0\n"); close(sockfd); events[i].data.fd = -1; } char* p = (char *)&clientaddr.sin_addr; sprintf(szAddr, "%d.%d.%d.%d", *p, *(p+1), *(p+2), *(p+3)); printf("recv %s from ip:%s\n",line,szAddr); //设置用于写操作的文件描述符 ev.data.fd=sockfd; //设置用于注测的写操作事件 ev.events=EPOLLOUT|EPOLLET; //修改sockfd上要处理的事件为EPOLLOUT epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); } else if(events[i].events&EPOLLOUT) { if(events[i].data.fd == -1) continue; sockfd = events[i].data.fd; write(sockfd, line, n); printf("send %s\n",line); //设置用于读操作的文件描述符 ev.data.fd=sockfd; //设置用于注测的读操作事件 ev.events=EPOLLIN|EPOLLET; char buf[256]="test"; sendto(sockfd,buf,strlen(buf),0,(sockaddr*)&clientaddr,addrlen); //修改sockfd上要处理的事件为EPOLIN epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); } } } }

 

标签:UDP,listenfd,addr,Epoll,实现,epoll,serveraddr,include,define
From: https://www.cnblogs.com/blj28/p/18318725

相关文章

  • 三种语言实现计算逆序对的数量(C++/Python/Java)
    题目给定一个长度为......
  • 使用PHP实现悲观锁的最佳实践。里面包含源码
    在数据库编程中,确保数据的一致性和完整性是非常重要的。当多个用户或线程同时访问和修改同一条数据记录时,可能会出现并发问题,比如读写冲突、数据丢失等。为了解决这些问题,我们可以使用并发控制机制,其中一种常见的方法就是悲观锁。什么是悲观锁?悲观锁是一种并发控制策......
  • Java实现七大排序(二)
    一.交换排序1.冒泡排序这个太经典了,每个学编程都绕不开的。原理跟选择排序差不多,不过冒泡排序是直接交换。publicstaticvoidbubbleSort(int[]array){for(inti=0;i<array.length-1;i++){for(intj=0;j<array.length-1-i;j++)......
  • vuejs设计与实现1-3
    Vue1.权衡的艺术2.框架设计的核心要素3.vue.js3设计思路1.权衡的艺术框架设计:在保持可维护性的同时让性能损失最小化;命令式VS声明式从范式上来看,视图层框架分为命令式和声明式。命令式框架:关注过程,性能优;声明式框架:关注结果,可维护性好框架设计需要考虑可......
  • 三种语言实现归并排序(C++/Python/Java)
    题目给定你一个长度为......
  • Python中如何实现字符串的查询和替换?
    在Python中,字符串的查询和替换是编程中常见的任务,它们可以通过Python的内置方法和库来高效实现。这些操作对于文本处理、数据清洗、日志分析等场景尤为重要。下面,我将详细阐述如何在Python中实现字符串的查询和替换,包括基础方法、高级技巧以及在实际应用中的注意事项。字符......
  • 实现el-table行展开可以定位到指定行功能
    实现方法1.拿到每一行的高度,2.再拿到每一行展开行的高度3.累加起来,让滚动条滚动到对应的高度tableScrollToRow(tableElement,rowIndex){constexpandedRows=tableElement.bodyWrapper.querySelectorAll(".el-table__expanded-cell");consttheTableRows=......
  • 微信小程序 - 最新详细实现 “餐厅食堂外卖点餐“ 全屏左右联动菜单列表功能界面,附带
    前言如果您需要“简约通用”的左右联动功能,请访问这篇文章。在微信小程序开发中,详解实现仿饿了么、美团外卖用户点餐左右联动界面,全屏适配左边菜单分类右侧商品菜单列表数据,顶部是搜索栏可搜索定位对应锚点位置及商品,左侧导航菜单点击时右侧商品跟着变化,反之列表滑动......
  • 鸿蒙 使用 Refresh 实现下拉刷新
    importpromptActionfrom'@ohos.promptAction'@Entry@ComponentstructIndex{@Staterefreshing:boolean=false@Statelist:number[]=Array(20).fill(Date.now())@Buildercontent(){Stack(){Row(){LoadingPro......
  • 硅纪元视角 | 类器官智能OI技术实现将人脑植入机器人
    在数字化浪潮的推动下,人工智能(AI)正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展,捕捉行业动态;提供深入的新闻解读,助您洞悉技术背后的逻辑;汇聚行业专家的见解,分享独到的视角和思考;精选对您有价值的信息,帮助您在AI时代中把握机遇。1分钟速览新闻  人......