2024.03.05作业

news2024/11/26 2:02:17

select实现tcp并发服务器

#include "test.h"

#define SER_IP "192.168.42.106"
#define SER_PORT 8888
 
int create_socket()
{
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd == -1)
    {
        perror("socket error");
        exit(-1);
    }
    printf("sfd = %d\n", sfd);

    return sfd;
}

int start_reuse(int sfd)
{
    int reuse = -1; 
    if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
    {
        perror("setsockopt error");
        exit(-1);
    }
    printf("端口号快速重用成功\n");

    return reuse;
}

void start_listen(int sfd)
{
    if (listen(sfd, 128) == -1)
    {
        perror("listen error");
        exit(-1);
    }
    printf("listen success\n");
}

int main(int argc, const char *argv[])
{
    int sfd = create_socket();

    int reuse = start_reuse(sfd);
 
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(SER_PORT);
    sin.sin_addr.s_addr = inet_addr(SER_IP);
    if (bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
    {
        perror("bind error");
        return -1;
    }

    start_listen(sfd);

    struct sockaddr_in cin;
    socklen_t socklen = sizeof(cin);
    int newfd = -1;
    char sbuf[128] = "";

    fd_set readfds, tempfds;
    FD_ZERO(&readfds);
    FD_SET(0, &readfds);
    FD_SET(sfd, &readfds);

    int maxfd = sfd;
    struct sockaddr_in cin_arr[1024];

    while(1)
    {
        tempfds = readfds;

        int res = select(maxfd + 1, &tempfds, NULL, NULL, NULL);
        if (res == -1)
        {
            perror("select error");
            exit(-1);
        }
        else if (res == 0)
        {
            printf("time out\n");
            exit(-1);
        }

        for (int i = 0; i < maxfd; i++)
        {
            if (!FD_ISSET(i, &tempfds))
            {
                continue;
            }

            if (i == sfd)
            {
                newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);
                if (newfd == -1)
                {
                    perror("accept error");
                    exit(-1);
                }

                printf("newfd=%d 您已有新客户上线\n", newfd);
                printf("客户端IP: %s, 端口号: %d\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port));

                FD_SET(newfd, &readfds);
                cin_arr[newfd] = cin;
                if (newfd > maxfd)
                {
                    maxfd = newfd;
                }
            }
            else if (i == 0)
            {
                fgets(sbuf, sizeof(sbuf), stdin);
                sbuf[strlen(sbuf) - 1] = 0;
                printf("触发了键盘输入事件: %s\n", sbuf);

                for (int k = 4; k < maxfd; k++)
                {
                    send(k, sbuf, strlen(sbuf), 0);
                }
            }
            else
            {
                char rbuf[128] = "";
                bzero(rbuf, sizeof(rbuf));

                int res = recv(i, rbuf, sizeof(rbuf), 0);
                if (res == 0)
                {
                    printf("客户端已下线\n");
                    close(i);

                    FD_CLR(i, &readfds);
                    for (int j = maxfd; j >= 0; j--)
                    {
                        if (FD_ISSET(j, &readfds))
                        {
                            maxfd = j;
                            break;
                        }
                    }

                    continue;
                }

                printf("[%s:%d]: %s\n", inet_ntoa(cin_arr[i].sin_addr), ntohs(cin_arr[i].sin_port), rbuf);

                strcat(rbuf, "*_*");
                send(i, rbuf, strlen(rbuf), 0);
            }
        }
    }
    
    close(sfd);
 
    return 0;
}

poll实现tcp客户端

#include "test.h"

#define SER_IP "192.168.191.128"
#define SER_PORT 8888

#define CLI_IP "192.168.191.128"
#define CLI_PORT 9999
 
int create_socket()
{
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd == -1)
    {
        perror("socket error");
        exit(-1);
    }
    printf("sfd = %d\n", sfd);

    return sfd;
}

int start_reuse(int sfd)
{
    int reuse = -1; 
    if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
    {
        perror("setsockopt error");
        exit(-1);
    }
    printf("端口号快速重用成功\n");

    return reuse;
}

void start_listen(int sfd)
{
    if (listen(sfd, 128) == -1)
    {
        perror("listen error");
        exit(-1);
    }
    printf("listen success\n");
}

int main(int argc, const char *argv[])
{
    int sfd = create_socket();

    int reuse = start_reuse(sfd);
 
    struct sockaddr_in cin;
    cin.sin_family = AF_INET;
    cin.sin_port = htons(CLI_PORT);
    cin.sin_addr.s_addr = inet_addr(CLI_IP);
    if (bind(sfd, (struct sockaddr*)&cin, sizeof(cin)) == -1)
    {
        perror("bind error");
        return -1;
    }

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(SER_PORT);
    sin.sin_addr.s_addr = inet_addr(SER_IP);

    if (connect(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
    {
        perror("connect error");
        exit(-1);
    }
    printf("connect success\n");

    struct pollfd pfd[2];
    pfd[0].fd = 0;
    pfd[0].events = POLLIN;
    pfd[1].fd = sfd;
    pfd[1].events = POLLIN;

    char wbuf[128] = "";
    while(1)
    {
        int res = poll(pfd, 2, -1);
        if (res == -1)
        {
            perror("poll error");
            exit(-1);
        }
        else if (res == 0)
        {
            printf("time out\n");
            exit(-1);
        }

        if (pfd[0].revents == POLLIN)
        {
            bzero(wbuf, sizeof(wbuf));

            printf("请输入>>>");
            fgets(wbuf, sizeof(wbuf), stdin);
            wbuf[strlen(wbuf) - 1] = 0;
    
            send(sfd, wbuf, strlen(wbuf), 0);
            printf("发送成功\n");

            if (strcmp(wbuf, "quit") == 0)
            {
                break;
            }
        }
        
        if (pfd[1].revents == POLLIN)
        {
            bzero(wbuf, sizeof(wbuf));
            recv(sfd, wbuf, sizeof(wbuf), 0);

            printf("收到消息: %s\n", wbuf);
        }
    }
    
    close(sfd);
 
    return 0;
}

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

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

相关文章

如何使用Python操作MySQL的各种功能?高级用法?

当今互联网时代&#xff0c;数据处理已经成为了一个非常重要的任务。而MySQL作为一款开源的关系型数据库&#xff0c;被广泛应用于各种场景。本篇博客将介绍如何使用Python操作MySQL的各种功能&#xff0c;以及一些高级用法。 连接MySQL 在Python中&#xff0c;我们可以使用p…

《操作系统真相还原》读书笔记二:环境搭建 xshell连接virtualbox

修改 sshd_config 使用 vi /etc/ssh/sshd_config命令进入sshd服务配置&#xff0c;键盘输入i进行编辑&#xff0c;将监听端口、监听地址前的 # 号去除&#xff0c;开启允许远程登录&#xff0c;开启使用用户名密码来作为连接验证。修改完成&#xff0c;按一下Esc&#xff0c;输…

汽车级瞬态抑制TVS二极管优势特性及型号大全

汽车级瞬态抑制TVS二极管是一种高性能的防浪涌过电压电路保护元器件&#xff0c;能够在瞬态电压过高的情况下提供可靠的保护。它能够迅速响应并吸收过电压&#xff0c;将其导向地线&#xff0c;从而保护车辆的电子设备免受损坏。东沃汽车级TVS二极管具有以下几个关键优势&#…

安卓Activity的深度探索:任务栈管理、启动模式及屏幕旋转策略的分析与应用

摘要 本文旨在深入探讨安卓Activity作为Android应用架构基石的重要概念&#xff0c;集中研究其任务栈管理机制、启动模式以及对屏幕旋转事件的响应策略。通过对这些核心特性的详尽阐述、优劣分析以及优化方案的讨论&#xff0c;为开发者优化用户体验、提升应用性能提供理论指导…

蓝牙系列二:BLE协议各层的形象化理解

对于蓝牙的协议栈模型已经不再陌生&#xff0c;但是看过相关的文档还是有些没法理解协议栈每层的区别以及每层的功能作用。本文还是继续学习韦东山讲解的蓝牙&#xff0c;对于初学者还是有很好的帮助作用&#xff0c;下面是韦东山老师形象化协议栈的框图&#xff1a; 下面还是把…

[java] 23种设计模式之责任链模式

1.1例子 公司请假系统&#xff0c;业务逻辑如下&#xff1a; 不超过3天的&#xff0c;组长审批 超过3天且小于7天的&#xff0c;总监审批 超过7天且小于15天的&#xff0c;部长审批 超过15天&#xff0c;前端直接拒绝&#xff0c;不会进入审批流程&#xff08;违反了公司的请假…

GIS之深度学习06:CUDA12安装(适配版)

CUDA&#xff08;Compute Unified Device Architecture&#xff09;是NVIDIA开发的并行计算平台和编程模型&#xff0c;用于利用NVIDIA GPU的并行计算能力&#xff0c;它允许开发者使用类似于C语言的编程语言编写并行程序&#xff0c;利用GPU的大规模并行计算能力加速各种类型的…

three.js如何实现简易3D机房?(一)基础准备-下

接上一篇&#xff1a; three.js如何实现简易3D机房&#xff1f;&#xff08;一&#xff09;基础准备-上&#xff1a;http://t.csdnimg.cn/MCrFZ 目录 四、按需引入 五、导入模型 四、按需引入 index.vue文件中 <template><div class"three-area">&l…

OJ习题之——圆括号编码

圆括号编码 1.题目描述2.完整代码3.图例演示 1.题目描述 题目描述 令Ss1 s2 …sn是一个规则的圆括号字符串。S以2种不同形式编码&#xff1a; &#xff08;1&#xff09;用一个整数序列Pp1 p2 … pn编码&#xff0c;pi代表在S中第i个右圆括号的左圆括号数量。&#xff08;记为…

一本书讲透ChatGPT,实现从理论到实践的跨越!大模型技术工程师必读

程序员如何选择职业赛道&#xff1f; 文章目录 程序员如何选择职业赛道&#xff1f;前言**作者简介**目录直播预告 前言 OpenAI 在 2022 年 11 月推出了人工智能聊天应用—ChatGPT。它具有广泛的应用场景&#xff0c;在多项专业和学术基准测试中表现出的智力水平&#xff0c;不…

esp32 C3和S3 开发板电流对比

出去好奇用合宙家的 lot power 测了两块开发板的运行电流。 esp32 S3 (嘉立创开发板 8N8 版本) 模式 电流downloa模式49 毫安空代码91 毫安light mode27 毫安deep mode25 毫安delay 40 毫安 esp32 C3 无串口芯片 &#xff08;合宙 9.9 元版本&#xff09; 模式 …

E33NCHA-LNN-NS-00主要特点

E33NCHA-LNN-NS-00是一款由Kollmorgen公司生产的高性能伺服电机&#xff0c;专门设计用于对运动系统进行精确控制。 以下是这款伺服电机的一些主要特点&#xff1a; 高扭矩密度&#xff1a;该电机能够在其尺寸下提供较大的扭矩输出&#xff0c;这对于空间有限的应用场合尤为重…

rocketmq Listener 消费消息的优雅方式(基于SPEL)

DefaultMQPushConsumer 配置 package repayment.config;import cn.itcast.wanxinp2p.repayment.message.diy.DefaultMessageListenerConcurrently; import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; import org.apache.rocketmq.client.exception.MQClient…

go语言基础 -- 文件操作

基础的文件操作方法 go里面的文件操作封装在os包里面的File结构体中&#xff0c;要用的时候最好去查下官方文档&#xff0c;这里介绍下基本的文件操作。 打开关闭文件 import("os" ) func main() {// Open返回*File指针&#xff0c;后续的操作都通过*File对象操作…

【XR806开发板试用】第一篇-基于ArchLinux配置开发环境并烧录

前段时间很幸运的申请到了XR806的这块开发板子。由于出差、生病还有各种事情的影响&#xff0c;这周末才有空拿出来收到的板子把玩一番。前段时间也抽空看了看其他工程师的体验文章。初步了解到全志为这块板子提供了比较方便的Linux开发环境。嗯&#xff0c;毕竟搞嵌入式嘛&…

Python乱码恢复

比如说网页是ISO-8859-1编码&#xff0c;然后requests得到的是乱码&#xff0c; 那么这样操作就可以还原数据&#xff1a;res.text.encode(‘ISO-8859-1’).decode(‘utf-8’) 乱码恢复网站&#xff0c;可以知道是什么编码http://www.mytju.com/classCode/tools/messyCodeReco…

【深度学习笔记】计算机视觉——风格迁移

风格迁移 摄影爱好者也许接触过滤波器。它能改变照片的颜色风格&#xff0c;从而使风景照更加锐利或者令人像更加美白。但一个滤波器通常只能改变照片的某个方面。如果要照片达到理想中的风格&#xff0c;可能需要尝试大量不同的组合。这个过程的复杂程度不亚于模型调参。 本…

2024-阿里巴巴灵犀互娱校招内推

灵犀互娱是阿里集团旗下研运一体游戏品牌&#xff0c;在业务模式上&#xff0c;灵犀互娱面向全球&#xff0c;研运一体&#xff0c;坚持精品&#xff0c;打造爆款&#xff0c;重视服务玩家。 访问链接即刻开启内推&#xff1a;https://talent.lingxigames.com/campus/qrcode/…

第十二篇:学习python数据清洗

文章目录 一、啥是数据清洗二、将表格数据导入pandas中1. 准备工作2. 引入csv文件2.1 引入pandas库2.2 读取文件/修改名称3.2 快速浏览数据2.4 修改名字2.5 查找缺失值2.6 删除缺失值 3. 引入Excel文件3.1 引入pandas库3.2 读取Excel文件的人均GDP数据3.3 查看数据类型和non-nu…

速卖通关键字搜索API接口实战:Python代码与搜索策略解析

一、速卖通关键字搜索API简介 速卖通&#xff08;AliExpress&#xff09;作为阿里巴巴旗下的国际电商平台&#xff0c;为卖家和买家提供了便捷的交易渠道。其开放平台提供的API接口允许开发者集成速卖通的各种功能&#xff0c;其中之一就是关键字搜索API。通过这个API&#xf…