首页 > 其他分享 >select poll epoll

select poll epoll

时间:2023-05-14 22:26:05浏览次数:31  
标签:lfd include addr epoll int ret saddr poll select

# select

 

 

/*  select阻塞函数,多次还是需要while,在新建客户端方面有没有都一样
        因为accept多次也需要while
    但在判断客户端是否有数据到来方面
        使用了select就不需要创建多个线程或进程判断了,select可以批量判断
*/
#include <stdio.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd == -1)
    {
        perror("socket");
        exit(-1);
    }

    char *buf = "192.168.248.128";
    int ip;
    inet_pton(AF_INET, buf, &ip);

    struct sockaddr_in saddr;
    saddr.sin_addr.s_addr = ip;
    saddr.sin_port = htons(9999);
    saddr.sin_family = AF_INET;

    // 绑定
    int ret = bind(lfd, (struct sockaddr *) &saddr, sizeof(saddr));
    if(ret == -1)
    {
        perror("bind");
        exit(-1);
    }
    ret = listen(lfd, 5);
    if(ret == -1)
    {
        perror("listen");
        exit(-1);
    }
    fd_set readfds, tmp; // 因为select返回时,内核会修改set,为了能够实现多次监听,需要一个副本记录原始set
    FD_ZERO(&readfds);
    FD_SET(lfd, &readfds);
    int maxfd = lfd; // 需要监听的最大序号的描述符


    while(1)
    {
        tmp = readfds;
        ret = select(maxfd + 1, &tmp, NULL, NULL, NULL);
        if(ret == -1)
        {
            perror("select");
            exit(-1);
        }
        else if(ret == 0)
        {
            continue;
        }
        else
        {
            if(FD_ISSET(lfd, &tmp)) // 是否有新的客户端到达
            {
                struct sockadd_in client_addr;
                int client_addr_len = sizeof(client_addr);
                int cfd = accept(lfd, (struct sockaddr *) &client_addr, &client_addr_len);
                FD_SET(cfd, &readfds);
                maxfd = cfd > maxfd ? cfd : maxfd;
            }
            for(int i = lfd + 1; i < maxfd + 1; i++) // 已经到达的客户端是否写了数据到我的读缓冲区
            {
                if(FD_ISSET(i, &tmp)) // 如果我的读缓冲区有数据
                {
                    char readBuf[1024];
                    int read_len = read(i, readBuf, sizeof(readBuf)); // 读取数据
                    if(read_len == 0)
                    {
                        printf("客户端连接断开······");
                        close(i); // 既然关闭了连接,则close描述符
                        FD_CLR(i, &readfds); // 在监听集合中删除相应描述符
                    }
                    else if(read_len == -1)
                    {
                        perror("read");
                        exit(-1);
                    }
                    else
                    {
                        printf("recv info : %s\n", readBuf);
                        write(i, readBuf, strlen(readBuf) + 1);
                    }
                }

            }
        }


    }
    close(lfd);














    return 0;
}

 

# poll

 

 

#include <stdio.h>
#include <sys/select.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <poll.h>
int main()
{
    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd == -1)
    {
        perror("socket");
        exit(-1);
    }

    char *buf = "192.168.248.128";
    int ip;
    inet_pton(AF_INET, buf, &ip);

    struct sockaddr_in saddr;
    saddr.sin_addr.s_addr = ip;
    saddr.sin_port = htons(9999);
    saddr.sin_family = AF_INET;

    // 绑定
    int ret = bind(lfd, (struct sockaddr *) &saddr, sizeof(saddr));
    if(ret == -1)
    {
        perror("bind");
        exit(-1);
    }
    ret = listen(lfd, 5);
    if(ret == -1)
    {
        perror("listen");
        exit(-1);
    }
    struct pollfd fds[1024]; // poll 是通过结构体数组
    for(int i = 0; i < 1024; i++)
    {
        fds[i].fd = -1;
        fds[i].events = POLLIN;
    }
    int cnt = 0;
    
    while(1)
    {
        ret = poll(fd, cnt + 1, -1);
        if(ret == -1)
        {
            perror("poll");
            exit(-1);
        }
        else if(ret == 0)
        {
            continue;
        }
        else
        {
            if(fds[0].revents & POLLIN) // 是否有新的客户端到达,用&是因为防止revents是多个状态的|
            {
                struct sockadd_in client_addr;
                int client_addr_len = sizeof(client_addr);
                int cfd = accept(lfd, (struct sockaddr *) &client_addr, &client_addr_len);
                int i;
                for(i = 1; i < 1024 && fds[i].fd != -1; i++);
                fds[i].fd = cfd;
                fds[i].events = POLLIN;
                cnt = i > cnt ? i : cnt;
            }
            for(int i = 0; i < cnt + 1; i++) // 已经到达的客户端是否写了数据到我的读缓冲区
            {
                if(fds[i].revents & POLLIN) // 如果我的读缓冲区有数据
                {
                    char readBuf[1024];
                    int read_len = read(i, readBuf, sizeof(readBuf)); // 读取数据
                    if(read_len == 0)
                    {
                        printf("客户端连接断开······");
                        close(i); // 既然关闭了连接,则close描述符
                        FD_CLR(i, &readfds); // 在监听集合中删除相应描述符
                    }
                    else if(read_len == -1)
                    {
                        perror("read");
                        exit(-1);
                    }
                    else
                    {
                        printf("recv info : %s\n", readBuf);
                        write(i, readBuf, strlen(readBuf) + 1);
                    }
                }

            }
        }


    }
    close(lfd);














    return 0;
}

 

# epoll

 

 

 

 

标签:lfd,include,addr,epoll,int,ret,saddr,poll,select
From: https://www.cnblogs.com/WTSRUVF/p/17399993.html

相关文章

  • 基本的SELECT语句
    3.基本的SELECT语句3.1SELECT...SELECT1;#没有任何子句SELECT7/3;#没有任何子句 3.2SELECT...FROM#语法:SELECT标识选择哪些列FROM标识从哪个表中选择#选择全部列:SELECT*FROMemployees; 3.3列的别名#1.直接在列名后空格加别名SELECTlast_n......
  • macOS terminal select text bug All In One
    macOSterminalselecttextbugAllInOne内存溢出❓bugs❌mousetrackingmodesolution✅Youhavesomehowactivatedtheterminal'smousetrackingmode.#resetmousetrackingmode$resethttps://apple.stackexchange.com/a/329807/346428demos(......
  • 为什么SELECT * 会导致查询效率低
    1.不需要的列会增加数据传输时间和网络开销1.用“SELECT*”数据库需要解析更多的对象、字段、权限、属性等相关内容,在SQL语句复杂,硬解析较多的情况下,会对数据库造成沉重的负担。2.增大网络开销;*有时会误带上如log、IconMD5之类的无用且大文本字段,数据传输size会几何增涨。......
  • el-autocomplete select事件传递多个参数
    问题<el-autocompletev-model="state":fetch-suggestions="querySearchAsync"placeholder="请输入内容"@select="handleSelect"></el-autocomplete>这是ElementUI官方文档中 el-autocomplete 的示例,而这里的 handleSelec......
  • jquery ui dialog 遮拦 select的解决方法
    <scripttype="text/javascript"src="/js/jquery.bgiframe.min.js"></script>  1.    引用以上JS代码。 注意:jquery与jquery.bgiframe插件的对应版本  2.    JS代码加入红色部分         $("#dialog-editor").dialog({ bgiframe:true, ......
  • Jquery操作select汇总
    转载:http://www.cnblogs.com/pepcod/archive/2012/07/03/JavaScript.html//Query获取Select选择的Text和Value:$("#select_id").change(function(){//code...});//为Select添加事件,当选择其中一项时触发varcheckText=$("#select_id").find("option:selected&qu......
  • 如何进行MySQL源码调试(一条select语句的执行流程)
    一、背景MySQL是当今世上最受欢迎的使用最广泛的开源数据库,它的繁荣离不开它的开源特性。放在过去商业数据库的时代,大家都没有机会接触到数据库的源代码,但在如今开源数据库的时代,越来越多的人开始研究数据库的源码,并给社区贡献代码,MySQL官方每次发布新版本都要感谢一些在社区上贡......
  • ant-select数据会发生卡顿问题解决
    <a-selectv-model="form.region"show-searchplaceholder="请选择"option-filter-prop="children"@search="handleSearch"@popupScroll="handlePopu......
  • Linux之select、poll、epoll讲解
    目录1select、poll、epoll1.1引言1.2IO和Linux内核发展1.2.1整体概述1.2.2阻塞IO1.2.3非阻塞IO1.2.4select1.2.5共享空间1.2.6零拷贝1.3select1.3.1简介1.3.2select缺点1.4poll介绍1.4.1与select差别1.4.2poll缺点1.5epoll1.5.1ep......
  • jquery select 操作
    //jQuery获取Select选择的Text和Value:varcheckText=jQuery("#select_id").find("option:selected").text();//获取Select选择的TextvarcheckValue=jQuery("#select_id").val();//获取Select选择的optionValuevarcheckIndex=jQuery("#sel......