select实现echo服务器的并发

news2024/9/29 9:23:09

select实现echo服务器的并发

代码实现

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/time.h>
#include <unistd.h>


#define MAX_CLI 50

int clients[MAX_CLI];
struct sockaddr_in clientaddr;
socklen_t len = sizeof(clientaddr);

int socket_create(int port) {//创建并绑定网络监听的socket套接字
    int fd;
    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }
    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_port = htons(port);
    if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("bind");
        exit(EXIT_FAILURE);
    }
    if (listen(fd, 20) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }
    return fd;
}
int recv_msg(int fd, char *buff, int size) { 

    int rsize = recv(fd, buff, sizeof(char ) * size, 0);
    if (rsize <= 0) {
        return -1;
    }
    printf("Recv : %s\n", buff);
    return 0;
}

int send_msg(int fd, char *buff, int size) {
    int ssize = send(fd, buff, sizeof(char ) * size, 0);
    if (ssize <= 0) {
        return -1;
    }
    printf("Send success!\n");
    return 0;
}

void echo_work(int server_listen) {
    for (int i = 0; i < MAX_CLI; i++) clients[i] = -1;//初始化数组
    while (1) {
        fd_set rfds;
        FD_ZERO(&rfds);
        FD_SET(server_listen, &rfds);
        int max_fd = server_listen;

        for (int i = 0; i < MAX_CLI; i++) {
            int fd = clients[i];
            if (fd != -1) {
                FD_SET(fd, &rfds);
                max_fd = fd > max_fd ? fd : max_fd;
            }
        }

        int ret = select(max_fd + 1, &rfds, NULL, NULL, NULL);
        if (ret < 0) {
            perror("select");
            exit(EXIT_FAILURE);
        }
        if (FD_ISSET(server_listen, &rfds)) {
            int clientfd;
            if((clientfd = accept(server_listen, (struct sockaddr *)&clientaddr, &len)) < 0) {
                perror("accept");
                exit(EXIT_FAILURE);
            }
            printf("one client accpet succes\n");
            for (int i = 0; i < MAX_CLI; i++) {
                if (clients[i] == -1) {
                    clients[i] = clientfd;
                    break;
                }
            } 
        }

        for (int i = 0; i < MAX_CLI; i++) {
            int fd = clients[i];
            if (fd != -1 && FD_ISSET(fd, &rfds)) {
                char buff[1024] = {0};
                if (recv_msg(fd, buff, 1024) < 0) {
                    clients[i] = -1;
                    close(fd);
                }//接收数据

                if (send_msg(fd, buff, 1024) < 0) {
                    clients[i] = -1;
                    close(fd);
                }//回显数据
            }
        }
    }
    
    return ;
}


int main() {
    int server_listen;

    if ((server_listen = socket_create(8080)) < 0) {
        perror("socket_create");
        exit(EXIT_FAILURE);
    }
    
    echo_work(server_listen);

    return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1614710.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

14. Spring AOP(二)实现原理

源码位置&#xff1a;spring_aop 上一篇文章中我们主要学习了AOP的思想和Spring AOP使用&#xff0c;本文讲的是Spring是如何实现AOP的&#xff0c;Spring AOP是基于动态代理来实现AOP的&#xff0c;在将动态代理之前先来了解一下什么是代理模式。 1. 代理模式 在现实中就有许…

【算法刷题 | 回溯思想 07】4.18(全排列、全排列 ||)

文章目录 11.全排列11.1题目11.2解法&#xff1a;回溯11.2.1回溯思路&#xff08;1&#xff09;函数返回值以及参数&#xff08;2&#xff09;函数返回值&#xff08;3&#xff09;遍历过程 11.2.2代码实现 12.全排列 ||12.1题目12.2解法&#xff1a;回溯12.2.1回溯思路12.2.3代…

教师编制可以跨市调动吗

在教育的广阔天地中&#xff0c;我们常常面临各种职业发展的选择。作为一名教师&#xff0c;是否能够实现跨市调动&#xff0c;这不仅是一个职业发展的问题&#xff0c;更关系到个人生活和职业规划的诸多方面。今天&#xff0c;我们就来探讨一下&#xff0c;拥有编制身份的教师…

2024免费专为Mac用户设计的清理和优化工具CleanMyMac X

CleanMyMac X是一款专为Mac用户设计的清理和优化工具。以下是对CleanMyMac X的详细介绍&#xff1a; 一、主要功能 系统清理&#xff1a;CleanMyMac X能够智能扫描Mac的磁盘空间&#xff0c;识别并清理各种垃圾文件&#xff0c;这些垃圾文件包括重复文件、无用的语言安装包、i…

模拟信号的离散化

本文介绍模拟信号的离散化。 1.采样定理 定义&#xff1a;若想重建输入的模拟信号&#xff0c;采样频率必须大于等于输入模拟信号最高频率的2倍&#xff0c;即&#xff1a; 其中&#xff0c;为采样频率&#xff0c;为输入模拟信号最高频率 否则&#xff0c;信号会发生混叠 2…

攻防世界---misc---easycap

1.下载附件是一个流量包&#xff0c;拿到wireshark中分析 2.查看分级协议 3.过滤data 4.追踪tcp流 5.得到flag

EUV光刻机机密文件被盗 | 百能云芯

4月22日消息&#xff0c;据法国媒体LeMagIT报道&#xff0c;日本光学技术领导厂商 Hoya Corporation&#xff08;豪雅&#xff09;最近遭遇了勒索软件的攻击&#xff0c;其总部和多个业务部门的IT系统遭受波及。据称超过 170 万份内部文件流失&#xff0c;其包括EUV掩模坯料和光…

根据表格该列数据的长度动态变化该列的宽度;

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、代码前言 在使用elementui的表格将数据展示出来时,我们想根据表格该列数据的长度动态变化该列的宽度; 1.看了一下elementui文档有一个 width 的属性,可用它来修改对应列。 2.那么我们需要拿到该列的所有数据去比较…

为何3D动画工作室偏爱使用在线渲染农场?

随着市场需求的不断增长和生产挑战的加剧&#xff0c;3D动画工作室面临着前所未有的压力。为了有效应对这些挑战&#xff0c;众多工作室选择了使用网络渲染农场。这种选择使他们能够借助网络渲染农场的强大渲染能力和高度灵活的资源配置&#xff0c;以此优化他们的工作流程&…

JAVA学习笔记27(异常)

1.异常 ​ *异常(Exception) ​ *快捷键 ctrl alt t 选中try - catch ​ *如果进行了异常处理&#xff0c;那么即使出现了异常&#xff0c;程序可以继续执行 1.1 基本概念 ​ *在Java语言中&#xff0c;将程序执行中发生的不正常情况称为"异常"(开发过程中的语…

Spring Boot 自动装配执行流程

Spring Boot 自动装配执行流程 Spring Boot 自动装配执行流程如下&#xff1a; Spring Boot 启动时会创建一个 SpringApplication实例&#xff0c;该实例存储了应用相关信息&#xff0c;它负责启动并运行应用。实例化 SpringApplication 时&#xff0c;会自动装载META-INF/spr…

HarmonyOS ArkUI滚动类组件-List、ListItem

List 是很常用的滚动类容器组件之一&#xff0c;它按照水平或者竖直方向线性排列子组件&#xff0c; List 的子组件必须是 ListItem &#xff0c;它的宽度默认充满 List 的宽度。 List定义介绍 interface ListInterface {(value?: { initialIndex?: number; space?: numbe…

隐藏表头和最高层级的复选框

隐藏表头和最高层级的复选框 <!-- 表格 --><el-tableref"tableRef"v-loading"tableLoading"default-expand-allclass"flex-1 !h-auto"row-key"regionId":header-cell-class-name"selectionClass":row-class-name&q…

HarmonyOS ArkUI实战开发-窗口模块(Window)

窗口模块用于在同一物理屏幕上&#xff0c;提供多个应用界面显示、交互的机制。 对应用开发者而言&#xff0c;窗口模块提供了界面显示和交互能力。对于终端用户而言&#xff0c;窗口模块提供了控制应用界面的方式。对于操作系统而言&#xff0c;窗口模块提供了不同应用界面的…

深度学习500问——Chapter08:目标检测(3)

文章目录 8.2.7 DetNet 8.2.8 CBNet 8.2.7 DetNet DetNet是发表在ECCV2018的论文&#xff0c;出发点是现有的检测任务backbone都是从分类任务衍生而来的&#xff0c;因此作者想针对检测专用的backbone做一些讨论和研究而设计了DetNet&#xff0c;思路比较新奇。 1. Introduct…

ROS机器人实战,对标古月老师HRMRP机器人(一)——机器人总体方案设计

咳咳&#xff01;这个是自己的毕业设计&#xff0c;内容比较多就拆开发。设计实现了一款SLAM移动机器人&#xff0c;加机械臂完成视觉识别抓取的&#xff0c;同时还有语音识别控制、QT上位机控制、Web网页控制。前几年看古月老师的视频&#xff0c;看到古月老师设计的HRMRP&…

【c++】vector模拟实现与深度剖析

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;c笔记仓 vector涉及到许多细节问题&#xff0c;比如双层深拷贝&#xff0c;迭代器失效等&#xff0c;本篇文章我们通过模拟实现来深度理解这块的内容 目录 1.基本框架2.构造和销毁3.元素访问4.获取…

SpringBoot多数据源(一)

SpringBoot多数据源&#xff08;一&#xff09; 1.多数据源使用场景1.1 业务复杂&#xff08;数据量大&#xff09;1.2 读写分离 2.多数据源配置3.应用4.测试 1.多数据源使用场景 1.1 业务复杂&#xff08;数据量大&#xff09; 简单理解就是业务量复杂&#xff0c;将庞大的数…

基于Springboot的校园新闻网站

基于SpringbootVue的校园新闻网站的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页展示 校园新闻 论坛交流 留言反馈 后台登录 用户管理 新闻类型管理 校园新闻…