IO多路复用、域套接字

思维导图

面试题
TCP通信中的三次握手和四次:
客户端像向服务器端发送连接请求
服务器应答连接请求
客户端与服务器简历连接

客户端向服务器发送断开请求
服务器应答断开请求
服务器请求关闭连接
客户端发送确认应答

并行和并发的区别:
并行:把任务在不同的时间点交给处理器进行处理。在同一时间点,任务并不会同时运行。(单核cpu)。
并发:把每一个任务分配给每一个处理器独立完成。在同一时间点,任务一定是同时运行。(多个cpu)。

阻塞IO和非阻塞IO的区别:
阻塞IO会进行等待事件的产生,如果事件没有发生,会阻塞等待,不会执行后续的任务。
非阻塞如果等待的事件没有发生,会立即返回,继续后续的任务。

同步和异步的区别:
同步是表示任务有序的执行,下面的任务要等待上面的任务执行完成后才执行。
异步是多个任务可以并发执行,没有现货顺序。

描述IO多路复用的原理:
将多个阻塞任务的文件描述符,统一放入到一个检测容器中,然后用一个阻塞函数进行管理,如果检测容器中有一个或多个文件描述符对应的事件产生,就会解除阻塞,进而去执行相应的函数。

广播的相关内容:
主机之间是一对多的通信模式,使用UDP实现,广播地址=网络号+全是1的主机号,广播消息不允许通过路由器。发送端类似于UDP的客户端,接收端类似于UDP 的服务器端。

组播的相关内容:
主机之间是一对多,会发送消息给加入同一网络下的所有主机,会占用大量宽带,使用udp实现,广播是D类网络。发送端类似于UDP的客户端,接收端类似于UDP 的服务器端。

在使用套接字通信时,客户端一定不要绑定操作吗:
不一定,在使用报式套接字是需要绑定,因为系统不会自动绑定套接字文件。

目前学习的进程间的通信方式有哪些
信号、信号灯集、有名管道、无名管道、共享内存、套接字、消息队列

线程的同步互斥机制:
互斥:多个线程操作拥有临界资源的临界区的时候,一旦有一个线程正在操作的时候,其他线程都不能运行这段拥有临界资源的临界区,直到第一个线程运行结束, 剩下的其他线程再去抢夺运行权,保护临界资源。
同步:简单的理解成有顺序的互斥。通过互斥的手段,安排好每一个线程的运行顺序。


select实现TCP并发服务器

#include<myhead.h>
#define SER_PORT 8888//端口号
#define SER_IP "192.168.101.115"//ip地址

int main(int argc, const char *argv[])
{
    int sfd=socket(AF_INET,SOCK_STREAM,0);//1、创建套接字
    //AF_INET是网络通信的套接字
    //SOCK_STREAM是TCP通信协议
    //参数3:参数2指定协议后填0
    if(sfd==-1)//判断是否失败
    {
        perror("sfd error");
        return -1;
    }
    //2、绑定端口号和IP地址
    //2.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);//ip地址
    //2.2绑定
    if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
    {
        perror("bind error");
        return -1;
    }
    //套接字设置为被动监听
    if(listen(sfd,128)==-1)
    {
        perror("error");
        return -1;
    }
    //阻塞等待客户端的链接请求
    int newfd=-1;
    struct sockaddr_in cin;//定义结构体变量接受客户端地址信息结构体
    socklen_t addrlen=sizeof(cin);//用于接收客户端结构体的大小
    char buff[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;//备份一份readfds
        int res=select(sfd+1,&tempfds,NULL,NULL,NULL);//阻塞等待集合中的事件产生
        if(res==-1)
        {
            perror("select error");
            return -1;
        }
        else if(res==0)
        {
            printf("time out\n");
            return -1;
        }
        //当程序执行到此,说明集合中有事件产生,此时集合中只剩下本次触发事件的文件描述符

        for(int i=0;i<maxfd;i++)
        {
            //如果不是触发事件的文件描述符直接跳过
            if(!FD_ISSET(i,&tempfds))
            {
                continue;
            }
            //程序执行至此,表示当前i这个文件描述符触发了事件

            //判断是否触发事件
            if(i==sfd)
            {
                if((newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen))==-1)
                {
                    perror("accept error");
                    return -1;
                }
                printf("[%s   %d]:发来请求链接\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
                cin_arr[newfd]=cin;//将客户端地址信息结构体放入数组容器中
                FD_SET(newfd,&readfds);//将newfd放入readfds容器中页参与检测

                if(newfd>maxfd)//更新maxfd
                {
                    maxfd=maxfd;
                }
            }


            else if(FD_ISSET(0,&tempfds))//判断0号文件描述符是否触发事件
            {
                fgets(buff,sizeof(buff),stdin); //从终端输入数据
                buff[strlen(buff)-1]=0;
                printf("触发了键盘输入事件:%s\n", buff);

                for(int i=4;i<=maxfd;i++)//将该消息发送给所有客户端
                {
                    send(i,buff,sizeof(buff),0);
                }
                printf("发送成功\n");
            }
            else
            {
                //说明某个客户端发来消息了,遍历所有的客户端,判断是哪个发来的消息
                char rbuf[128]=""; //用于接收客户发发来的数据
                bzero(rbuf,sizeof(rbuf));//将容器清空

                int res=recv(i,rbuf,sizeof(rbuf)-1,0);
                if(res==0)
                {
                    printf("客户已经下线\n");
                    close(i);//关闭跟客户端通信的套接字
                }
                FD_CLR(i,&readfds);//将当前文件描述符移除容器

                for(int k=maxfd;k>=sfd;k--)
                {
                    if(FD_ISSET(k,&readfds))
                    {
                        maxfd=k;
                        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);
            printf("发送成功\n");
        }
    }

}

close(sfd);
return 0;
}
 

效果图

poll实现TCP客户端(没做出来)
 

#include<myhead.h>
#define SER_PORT 8888
#define SER_IP "192.168.101.115"
#define CLI_PORT 9999
#define CLI_IP "192.168.101.115"

int main(int argc, const char *argv[])
{
    //1、创建用于连接的客户端套接字
    int cfd = socket(AF_INET, SOCK_STREAM, 0);
    if(cfd == -1)
    {
        perror("socket error");
        return -1;
    }
    printf("socket success cfd = %d\n", cfd);    

    //设置端口号快速重用
    int reuse = 1;
    if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) ==-1)
    {
        perror("setsockopt error");
        return -1;
    }
    printf("端口号快速重用成功\n");
    //2、绑定端口号和ip地址(非必须)
    //2.1 填充客户端地址信息结构体
    struct sockaddr_in cin;
    cin.sin_family = AF_INET;
    cin.sin_port = htons(CLI_PORT);
    cin.sin_addr.s_addr = inet_addr(CLI_IP);

    //2.2 绑定端口号和IP
    if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");


   //3、连接服务器
    //3.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);    //服务器的IP地址

    //3.2 连接服务器
    if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
    {
        perror("connect error");
        return -1;
        }
    printf("连接成功!\n");

    //使用poll完成0号文件描述符和cfd文件描述符的多路复用
    //11、准备文件描述符容器
    struct pollfd pfds[2];
    pfds[0].fd = 0; //文件描述符
    pfds[0].events = POLLIN;    //检测读事件

    pfds[1].fd = cfd;       //文件描述符
    pfds[1].events = POLLIN;    //检测读事件


    //4、收发数据
    char wbuf[128] = "";
    while(1)
    {

        int res = poll(pfds, 2, -1);        //阻塞检测集合中是否有事件产生
        if(res == -1)
        {
            perror("poll error");
            return -1;
        }else if(res == 0)
        {
            printf("time out\n");
            return -1;
        }
        //程序执行至此,说明检测的文件描述符集合中有事件产生

        //判断是否为0号文件描述符产生事件
        if(pfds[0].revents == POLLIN)
        {
        
            fgets(wbuf, sizeof(wbuf), stdin);    //从终端上获取一个字符串
            wbuf[strlen(wbuf)-1] = '\0';      //将换行换成 '\0'

            //判断输入的字符串值
            if(strcmp(wbuf, "quit") ==0)
            {
                break;
            }


            //将数据发送给服务器
            send(cfd, wbuf, strlen(wbuf), 0);
        }

        //判断释放为cfd文件描述符中产生事件
        if(pfds[1].revents == POLLIN)
        {
            //将字符数组清空
            bzero(wbuf, sizeof(wbuf));
            recv(cfd, wbuf, sizeof(wbuf)-1, 0);
            printf("收到服务器消息为:%s\n", wbuf);
        }
    }
    //5、关闭套接字
    close(cfd);

    return 0;
}
 

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

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

相关文章

外包干了6天,技术明显进步。。。

我是一名大专生&#xff0c;自19年通过校招进入湖南某软件公司以来&#xff0c;便扎根于功能测试岗位&#xff0c;一晃便是近四年的光阴。今年8月&#xff0c;我如梦初醒&#xff0c;意识到长时间待在舒适的环境中&#xff0c;已让我变得不思进取&#xff0c;技术停滞不前。更令…

R语言Meta分析核心技术:从入门到精通

R语言作为一种强大的统计分析和绘图语言&#xff0c;在科研领域发挥着日益重要的作用。其中&#xff0c;Meta分析作为一种整合多个独立研究结果的统计方法&#xff0c;在R语言中得到了广泛的应用。通过R语言进行Meta分析&#xff0c;研究者能够更为准确、全面地评估某一研究问题…

Java毕业设计-基于springboot开发的Java时间管理系统-毕业论文+答辩PPT(附源代码+演示视频)

文章目录 前言一、毕设成果演示&#xff08;源代码在文末&#xff09;二、毕设摘要展示1、开发说明2、需求分析3、系统功能结构 三、系统实现展示1、管理员功能模块2、用户功能模块 四、毕设内容和源代码获取总结 Java毕业设计-基于springboot开发的Java时间管理系统-毕业论文答…

‘sc‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

问题描述&#xff1a; sc 不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。 通过mysql黑窗口命令 “sc delete 服务名” 删除mysql服务时系统报错&#xff1a;sc不是内部命令或外部命令 原因&#xff1a; 系统默认环境变量值发生变化&#xff1b; 解决&…

从零开始学习typescript系列6: typescript各种类型以及类型特殊使用

基础类型的分类 常用 boolean: 布尔值number: 支持2/8/10/16进制string: 字符串enum: 枚举类型&#xff0c;可根据value找到keyarray: 普通数组&#xff0c;有2种方式&#xff0c;string[]或者 Array<string>tuple: 特殊数组&#xff0c;指定数组里的每个元素的类型&am…

UE snap02 解析ASCII文本文件

UE snap02 解析ASCII文本文件 示例数据data.dat 11389477.2714892 3364559.73645693 0 11389471.5162524 3364567.8860295 0 11389471.5162524 3365813.09618369 0 11388329.6082659 3366184.85895869 0 11388320.4775297 3366197.78833087 0 11388270.6882384 3366214.84811…

爬虫实战-Python爬取百度当天热搜内容

爬虫实战-Python爬取百度当天热搜内容 学习建议学习目标预期内容目标分解热搜地址热搜标题热搜简介热搜指数小总结 代码实现总结 学习建议 本文仅用于学习使用&#xff0c;不做他用&#xff1b;本文仅获取页面的内容&#xff0c;作为学习和对Python知识的了解&#xff0c;不会…

Python从入门到精通秘籍十一

一、Python之自定义模块并导入 在Python中&#xff0c;我们可以自定义模块并将其导入到其他Python程序中使用。自定义模块可以包含函数、类、常量等&#xff0c;便于组织和重用代码。 下面是使用Python代码详细讲解自定义模块的创建和导入的例子&#xff1a; 假设我们有两个…

2040X系列 电子校准件

苏/州/新/利/通 2040X系列 电子校准件 300kHz&#xff5e;67GHz 简述 2040X系列电子校准件包括20402/20403/20404/20405/20409五种型号&#xff0c;覆盖频段300kHz&#xff5e;18GHz/10MHz&#xff5e;26.5GHz/10MHz&#xff5e;50GHz/10MHz&#xff5e;20GHz/10MHz&#xf…

KDD Cup 1999数据集

KDD Cup 1999数据集是一个用于计算机网络入侵检测的经典数据集。该数据集由美国加州大学欧文分校&#xff08;UCI&#xff09;的计算机科学系和加州大学伯克利分校&#xff08;UCB&#xff09;的法律计算机科学研究小组提供&#xff0c;并在1999年的KDD Cup数据挖掘竞赛中使用。…

redis学习-Set集合类型相关命令及特殊情况分析

目录 1. sadd key value1 value2 ... 2. smembers key 3. sismember key value 4. scard key 5. srem key value1 value2 ... 6. srandmember key num 7. spop key num 8. smove key1 key2 value 9. sdiff key1 key2 key3 ... 10. sinter key1 key2 ... 11. sunion key1 key2 .…

Android 11系统启动流程

在Android 11系统启动流程中&#xff0c;系统启动主要经历了以下几个阶段&#xff1a; 引导加载程序&#xff08;Bootloader&#xff09;启动&#xff1a; 当设备加电后&#xff0c;首先运行的是ROM Bootloader&#xff0c;它负责验证操作系统映像的完整性、初始化基本硬件并加…

Acwing1113. 红与黑

Problem: Acwing1113. 红与黑 文章目录 思路解题方法复杂度Code 思路 这是一道经典的洪水填充问题&#xff0c;可以使用dfs搜索和bfs搜索来解决。 ′ . ′ : . : ′.′:表示黑色瓷砖&#xff0c;‘#’:表示红色瓷砖&#xff0c;‘’表示黑色的瓷砖&#xff0c;并且你站在这块瓷…

Unix运维_Unix下配置PHP-7.x.x和Apache-2.x.x

Unix运维_Unix下配置PHP-7.x.x和Apache-2.x.x Apache HTTP Server (简称 Apache, 音译为: 阿帕奇) 是 Apache 软件基金会的一个开放源码的网页服务器。 Apache 源于 NCSAhttpd 服务器, 经过多次修改, 成为世界上最流行的 Web 服务器软件之一。 Apache 可以运行在几乎所有广泛…

鸿蒙一次开发,多端部署(二)从一个例子开始

本章通过一个天气应用&#xff0c;介绍一多应用的整体开发过程&#xff0c;包括UX设计、工程管理及调试、页面开发等。 UX设计 本示例中的天气应用包含主页、管理城市和添加城市三个页面&#xff0c;其中主页中又包含菜单和更新间隔两个弹窗&#xff0c;基本业务逻辑如下所示…

Aztec的客户端证明

1. 引言 隐私保护 zk-rollup 的证明生成与通用 zk-rollup 的证明生成有很大不同。原因是给定交易中存在特定数据&#xff08;由私有函数处理&#xff09;&#xff0c;我们希望保持完全私有。在本文中&#xff0c;我们探讨了用于证明私有函数正确执行的客户端证明生成&#xff…

arm-linux实现onvif server+WS-UsernameToken令牌验证

目录 一、环境搭建 1、安装openssl 2、安装bison 3、安装flex 二、gsoap下载 三、编译x86版本gsoap 四、编译arm-linux版本gsoap 1、交叉编译openssl 1.1、下载openssl 1.2、交叉编译 2、交叉编译zlib 2.1、下载zlib 2.2、交叉编译 3、交叉编译gsoap 3.1、编译过…

【嵌入式学习】Qtday03.21

一、思维导图 二、练习 自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面。&#xff08;不要使用课堂上的图片和代码&#xff0c;自己发挥&#xff0c;有利于后面项目的完成&#xff09; 要求&#xff1a; 1. 需要使用Ui界面文件进行界面设计 2. ui界面上的组件…

Spring Framework UriComponentsBuilder URL解析不当漏洞复现(CVE-2024-22259)

免责声明 由于传播、利用本CSDN所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任,一旦造成后果请自行承担! 一、产品介绍 Spring Framework 是一个开源的Java应用程序框架,UriComponentsBuilder是Spring Web中用于构建和操作…

C语言之---柔性数组

1.1前记 也许你从来没有听说过柔性数组这个概念&#xff0c;但是它是确实存在的。 C99中&#xff0c;结构中的最后一个元素允许是未知大小的数组&#xff0c;这就是柔性数组成员。 例如: struct st_type {int i;int a[0]; }; 有些编译器会报错无法编译可以改为&#xff1a…