首页 > 其他分享 >IO多路复用

IO多路复用

时间:2024-09-11 17:24:50浏览次数:3  
标签:addr 多路复用 int acceptfd IO sockfd 接字 include

epoll功能及参数:

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

功能:控制epoll属性,比如给红黑树添加节点。

参数: 1. epfd: epoll_create函数的返回句柄。

2. op:表示动作类型,有三个宏:

EPOLL_CTL_ADD:注册新的fd到epfd中

EPOLL_CTL_MOD:修改已注册fd的监听事件

EPOLL_CTL_DEL:从epfd中删除一个fd

3. 要操作的文件描述符

4. 结构体信息:

返回值:成功:0, 失败:-1

  1. 特点:

  1. 监听的文件描述符没有了限制。
  2. 异步IO,epoll当有世纪那唤醒之后,发生事件的文件描述符会主动的调用callback回调函数,拿到对应的文件描述符。不需要要轮询,效率高。
  3. epoll不需要构造表,只需要从用户空间拷贝到内核空间一次。

总结:

  • select:适用于小规模应用,简单易用但有文件描述符限制。
  • poll:比 select 更灵活,适用于中等规模应用,但性能瓶颈仍然存在。
  • epoll:最适合大规模、高并发应用,性能优越但在 Linux 上才可用。

代码小练习:每有一个客户端连接创建一个进程进行通信

思路:

  1. 创建套接字:使用 socket() 函数创建一个用于通信的套接字。
  2. 绑定地址:用 bind() 函数将套接字绑定到指定的 IP 地址和端口上。
  3. 监听连接:调用 listen() 函数,使服务器开始监听客户端的连接请求。
  4. 接受连接:使用 accept() 函数接受客户端连接请求,并创建一个新的套接字用于与客户端通信。
  5. 创建子进程:通过 fork() 函数创建一个子进程来处理客户端的通信。
  6. 通信处理:子进程使用 recv() 接收数据,处理完毕后通过 send() 发送响应。
  7. 关闭套接字:通信结束后,子进程关闭与客户端的套接字,父进程关闭监听套接字。

代码实现:

#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
// 处理子进程终止信号的处理函数
void handler(int sig)
{
    wait(NULL); // 回收子进程的资源
}
int main(int argc, char const *argv[])
{
    pid_t pid;
    char buf[128] = {0}; // 数据缓冲区
    int ret, acceptfd;
    
    // 1. 创建套接字(socket)-----------------》有手机
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket err");
        return -1;
    }
    printf("sockfd:%d\n", sockfd); // 打印套接字文件描述符

    // 2. 指定网络信息---------------------------》有号码
    struct sockaddr_in saddr, caddr;
    saddr.sin_family = AF_INET;            // 使用 IPV4 协议
    saddr.sin_port = htons(atoi(argv[1])); // 设置端口号
    // saddr.sin_addr.s_addr = inet_addr("192.168.50.13"); // 虚拟机IP
    // saddr.sin_addr.s_addr = inet_addr("0.0.0.0"); // 绑定到所有接口
    saddr.sin_addr.s_addr = INADDR_ANY; // 绑定到所有网络接口
    int len = sizeof(caddr);
    
    // 3. 绑定套接字(bind)------------------》绑定手机(插卡)
    if (bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
    {
        perror("bind err");
        return -1;
    }
    printf("bind ok\n");
    
    // 4. 监听套接字(listen)-----------------》待机
    if (listen(sockfd, 6) < 0)
    {
        perror("listen err");
        return -1;
    }
    printf("listen ok\n");
    
    // 5. 接收客户端连接请求(accept)--------》接电话
    signal(SIGCHLD, handler); // 设置信号处理方式
    
    while (1)
    {
        acceptfd = accept(sockfd, (struct sockaddr *)&caddr, &len);
        if (acceptfd < 0)
        {
            perror("accept err");
            return -1;
        }
        
        // 打印客户端信息
        printf("port:%d ip:%s\n", ntohs(caddr.sin_port), inet_ntoa(caddr.sin_addr));
        printf("acceptfd:%d\n", acceptfd);
        
        pid = fork(); // 创建子进程
        if (pid < 0)
        {
            perror("fork err");
            return -1;
        }
        else if (pid == 0)
        {
            // 6. 接收、发送数据(recv/send)------》通话
            while (1)
            {
                ret = recv(acceptfd, buf, sizeof(buf), 0);
                if (ret < 0)
                {
                    perror("recv err");
                    break;
                }
                else if (ret == 0)
                {
                    printf("client exit\n");
                    break;
                }
                else
                {
                    printf("buf:%s\n", buf); // 打印接收到的数据
                    memset(buf, 0, sizeof(buf)); // 清空缓冲区
                }
            }
            // 7. 关闭套接字(close)--------------》挂电话
            close(acceptfd);
            exit(0); // 结束子进程
        }
        else
        {
            close(acceptfd); // 父进程关闭通信描述符
        }
    }

    close(sockfd); // 关闭监听套接字

    return 0;
}

标签:addr,多路复用,int,acceptfd,IO,sockfd,接字,include
From: https://blog.csdn.net/weixin_63207763/article/details/142099533

相关文章

  • Stable Diffusion4.9一键安装教程SD(AI绘画软件)
    **无套路!**文末提供下载方式StableDiffusion是一款革命性的AI绘画生成工具,它通过潜在空间扩散模型,将图像生成过程转化为一个逐步去噪的“扩散”过程。与传统的高维图像空间操作不同,StableDiffusion首先将图像压缩到低维的潜在空间中,然后通过应用扩散过程来生成新的......
  • iOS开发-系统字体
    iOS开发-系统字体UIKIT_EXTERNUIFontTextStyleconstUIFontTextStyleExtraLargeTitleAPI_AVAILABLE(ios(17.0));UIKIT_EXTERNUIFontTextStyleconstUIFontTextStyleExtraLargeTitle2API_AVAILABLE(ios(17.0));UIKIT_EXTERNUIFontTextStyleconstUIFontTextStyleTitle1......
  • Attention Sinks 入门指南 - 实现无限长度文本生成的高效流式语言模型
    AttentionSinks简介AttentionSinks是一种新的注意力机制,可以让预训练语言模型生成无限长度的连贯文本,同时保持恒定的内存使用。它通过保留初始token的注意力信息(称为"注意力池"),并使用滑动窗口来处理最近的token,从而实现了高效的长文本生成。AttentionSinks......
  • POLIR-Society-Organization-Politics-Self-Health : {Love:SelfLove自爱Esteem自强}
    Love:Self-esteem:自尊tokeepyoualwaysatyourbeststate,whatever,whenever,wherever.TAKECAREOFOURSELVES.Materials:Clothes,Edible{Food,Water,Fruits};House,Equipments,Facilities,Utilities(Electricities,TapWater,Gas,...).Phones,Pl......
  • 自注意力机制(self-attention)
    自注意力机制self-attention红色框中的这四个向量是考虑了整个sequence后的输出,而且self-attention不仅可以使用一次,transformer中最重要的就是self-attention根据\(a^1\)找到和\(a^1\)相关的向量,比如如何计算\(a^1\)和\(a^4\)有多相关计算有很多不同的方法计算相关度\(......
  • 并发编程 - NSOperation&NSOperationQueue(多线程)
    ​​​​​​​并发编程-概述-CSDN博客并发编程-GCD的任务和队列-CSDN博客并发编程-NSOperation&NSOperationQueue(多线程)-CSDN博客并发编程-NSThread-CSDN博客引言在上篇博客中我们首先介绍了GCD的多线程方案,NSOperation和NSOperationQueue是Apple为我们提供的......
  • WPF Application.Current.Properties[key]=value
    usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows;usingSystem.Windows.Controls;usingSystem.Windows.Data;usingSystem.Windows.Documents;usingSystem.Windows.Input;......
  • Java服务端中的数据验证:使用Bean Validation与Spring Validator的最佳实践
    Java服务端中的数据验证:使用BeanValidation与SpringValidator的最佳实践大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在Java服务端开发中,数据验证是确保应用数据准确性和可靠性的关键步骤。本文将探讨BeanValidation和SpringValidator这两种数......
  • 逻辑回归(Logistic Regression)
    许多问题需要将概率估算值作为输出。由于线性回归无法保证输出值表示概率(介于零和一之间),所以需要逻辑回归——它是一种极其高效的概率计算机制。那么逻辑回归如何保证其输出表示概率?1.逻辑回归如何计算概率?碰巧,有一族函数称为“逻辑函数”,其输出满足上述条件。标准逻辑函数/S......
  • 实现keras.textvectorization自由tf-idf篇
    本篇,带你简略了解如何使用keras.textvectorization来处理词袋模型(tfidf)计算1、替换:如果发现以下内容实现存在障碍,请替换方法:适用sklearn来计算tf-idf,sklearn里也有包装比较好的各类如tfidfVectorize等模块方法,通过fit-transform来实现2、keras.textvectorization的区别及优......