首页 > 其他分享 >epoll用法

epoll用法

时间:2024-03-14 11:25:09浏览次数:17  
标签:struct epoll 用法 fd events data event

1.创建socketfd和epoll

  // 创建epollfd.
  int epfd = epoll_create(1);

 

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

2.绑定端口号

  struct sockaddr_in serveraddr;
  serveraddr.sin_family = AF_INET;
  serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
  serveraddr.sin_port = htons(17099);
  // 绑定.
  if (bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr)) == -1)
  {
    perror("bind");
    exit(-1);
  }

3. 监听

  // 监听.
  if (-1 == listen(sockfd, 10))
  {
    perror("listen");
    exit(-1);
  }

4.将这个fd加入epoll(水平触发)

  // 将socketfd添加到epoll.
  struct epoll_event ep_event;
  ep_event.events = EPOLLIN;
  ep_event.data.fd = sockfd;
  if (epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ep_event) == -1)
  {
    perror("epoll_ctl");
    exit(-1);
  }

5.声明epoll_event数组,然后循环epoll_wait

  struct epoll_event events[1024] = {0};
  while (1)
  {
    int nready = epoll_wait(epfd, events, 1024, -1);

6.遍历nready,然后判断是否是服务端socket

    for (int i = 0; i < nready; i++)
    {
      struct sockaddr_in clientaddr;
      socklen_t len = sizeof(clientaddr);
      char ip[20];
      if (events[i].data.fd == sockfd)
      {

7.然后accept获取客户端socket,并添加到epoll

        int client = accept(events[i].data.fd, (struct sockaddr *)&clientaddr, &len);
        inet_ntop(AF_INET, &(clientaddr.sin_addr), ip, len);
        printf("%d connect: ip %s port %d\n", client, ip, clientaddr.sin_port);
        // 将新的fd添加到epoll
        ep_event.data.fd = client;
        epoll_ctl(epfd, EPOLL_CTL_ADD, client, &ep_event);

8.如果epoll_wait有EPOLL_IN事件,则说明有消息,recv

      }else if(events[i].events & EPOLLIN){
        char buffer[1024] = {0};
        int count = recv(events[i].data.fd, &buffer, sizeof(buffer), 0);

9.如果这个count是-1,则说明recv错误;如果是0,则说明客户端断开;如果大于0,则说明有消息

        if (count == -1)
        {
          printf("recv error %m\n");
          continue;
        }
        else if (count == 0)
        {
          // 说明连接断开.
          printf("%d disconnect: ip %s port %d\n", events[i].data.fd, ip, clientaddr.sin_port);
          close(events[i].data.fd);
          epoll_ctl(epfd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
        }
        else
        {
          printf("recv: %s\n", buffer);
          send(events[i].data.fd, &buffer, count, 0);
        }

 

标签:struct,epoll,用法,fd,events,data,event
From: https://www.cnblogs.com/anlingxiao/p/18072441

相关文章

  • Java反射和注解基本用法
    Java注解和反射Java注解什么是注解Annotation是从JDK5.0开始引入的新技术Annotation作用:不是程序本身,可以对程序做出解释可以被其他程序(比如编译器)读取Annotation格式:注解是以@注解名在代码中存在的,还可以添加一些参数值,例如:@Service(value="")Annotation在哪......
  • 触发器的用法:同一视频,设置三个触发器,控制播放、暂停、退出
    控制按钮的设置1.用自选图形绘制“播放”“暂停”“退出”控制按钮,视频插入2.在PowerPoint中插入视频,点击视频选择,选择动画菜单,出现播放、暂停、停止动画,(WPS中似乎没有这个功能,也可能是本人使用的版本的原因)可以设置视频的播放、暂停、停止。添加动画效果3.分别为视频添加......
  • 关于Sql server数据类型HierarchyID 数据类型用法和递归显示完整路径
    SQLServer2008版本之后的新类型HierarchyID不知道大家有没有了解,该类型作为取代id,parentid的一种解决方案,让人非常惊喜。官方给的案例浅显易懂,但是没有实现我想要的基本功能,树形结构中完整名称路径的展示。本文末尾是一个完整路径的样例,需要更多基本操作可以参考文末微软链......
  • Golang - 三个点‘...‘的用法
    用法1)主要是用于函数有多个不定参数的情况,可以接受多个不确定数量的参数(可选参数)packagemainimport"fmt"functest(args...string){//可以接受任意个string参数for_,v:=rangeargs{fmt.Println(v)}}funcmain(){varstr=[]string{......
  • const的用法
    1、修饰局部变量constintn=5;intconstn=5;这两种写法都是一样的,都是表示变量n的值不能被改变了!但在用const修饰前,一定要给变量初始化!否则就不能再进行赋值了。2、修饰指针与指针常量2.1常量指针常量指针是指针指向的内容是常量。constint*n;intconst*n;数据......
  • 探究WPF中文字模糊的问题:TextOptions的用法
    有网友问WPF中一些文字模糊是什么问题。之前我也没有认真思考过这个问题,只是大概知道和WPF的像素对齐(pixelsnapping)、抗锯齿(anti-aliasing)有关,通过设置附加属性TextOptions.TextFormattingMode或者TextOptions.TextRenderingMode来解决。这次我也查了下资料,了解了这几个附加属性......
  • UVM宏解释+odt文件转doc+merge命令和difflib+python调用命令+clog2和系统函数+java添
    UVM宏解释UVM_DISABLE_AUTO_ITEM_RECORDINGhttps://blog.csdn.net/MGoop/article/details/127295965itemrecord的方法主要是用于记录事务信息的,原理是调用accept_tr,begin_tr,end_tr。似乎和波形上显示出各个事务相关。默认情况下,在调用get_next_item()和item_done()时自动......
  • Java多线程基础用法
    线程创建线程创建的三种方式:Thread(继承Thread类)自定义线程类继承Thread类重写run()方法。编写线程执行体创建线程对象,调用start()方法启动线程packagecom.lily.demo01;publicclassTestThreadextendsThread{@Overridepublicvoidrun(){for......
  • default在java中的用法 java里default
    介绍default是在java8中引入的关键字,也可称为Virtualextensionmethods——虚拟扩展方法。是指,在接口内部包含了一些默认的方法实现(也就是接口中可以包含方法体,这打破了Java之前版本对接口的语法限制),从而使得接口在进行扩展的时候,不会破坏与接口相关的实现类代码。为什么需要这......
  • Swoole 源码分析之 epoll 多路复用模块
    首发原文链接:Swoole源码分析之HttpServer模块大家好,我是码农先森。引言在传统的IO模型中,每个IO操作都需要创建一个单独的线程或进程来处理,这样的操作会导致系统资源的大量消耗和管理开销。而IO多路复用技术通过使用少量的线程或进程同时监视多个IO事件,能够更高效地处理大......