C/C++网络编程基础知识超详细讲解第三部分(系统性学习day13)

                                                    懒大王感谢大家的关注和三连支持~   

目录

前言

一、并发服务器

1.进程并发服务器

实例代码如下: 

2.线程并发服务器

实例代码如下: 

二、域通信

域通信TCP实例代码如下: 

三、广播与组播(UDP) 

1.广播

实例代码如下: 

 2.组播 

实例代码如下:

四、图解如下

 总结


前言

作者简介: 懒大王敲代码,正在学习嵌入式方向有关课程stm32,网络编程,数据结构C/C++等

今天给大家继续详细讲解网络编程基础知识,希望能够帮到大家!
欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💕 💕  💕 


一、并发服务器

1.进程并发服务器

消耗资源大,每连接进来一个客户端,你就要去开辟进程去服务那个客户端
            fork()
            举例:
                        if(fork()==0)  //子进程模块,不影响主进程中不断接收客户端连接
                        {
                            zhuanfa(&cfd);    
                        }

实例代码如下: 

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
// struct sockaddr_in client;
// int len = sizeof(client);void *zhuanfa(void *arg)
{int ret;int fd = *(int *)arg;char buf[1024];//接信息char buf1[50] = "猖狂,北伐!";while(1){bzero(buf,sizeof(buf));ret = recv(fd,buf,sizeof(buf),0);if(0 == ret){printf("客户%d离开了\n",fd);close(fd);return NULL;}else{printf("客户%d:%s\n",fd,buf); // printf("客户%d进来了,IP地址为%s,端口号为%d\n",fd,inet_ntoa(client.sin_addr),ntohs(client.sin_port));send(fd,buf1,strlen(buf1),0); }	}return NULL;
}int main(void)
{//socketint serfd = socket(AF_INET,SOCK_STREAM,0);if(0>serfd){perror("socket");return -1;}//bindstruct sockaddr_in ser;//netinet/in.hser.sin_family = AF_INET;ser.sin_port = htons(8888);ser.sin_addr.s_addr = inet_addr("192.168.10.5");if(bind(serfd,(struct sockaddr *)&ser,sizeof(ser))<0){perror("bind");return -1;}	//listenlisten(serfd,8);//acceptint cfd;pthread_t a;while(1){//不断接受不同的客户端,并分配一个服务员给客户对接,在线程进行通信cfd = accept(serfd,NULL,NULL);//accept保存客户信息到client// pthread_create(&a,NULL,zhuanfa,&cfd);// pthread_detach(a);if(fork()==0){zhuanfa(&cfd);	}}return 0;
}

2.线程并发服务器

占用资源资源比较小,代码维护起来困难
            pthread_create  //线程的创建
            pthread_detach    //给创建线程能自动收尸的能力 
            不自动:pthread_join
            
            printf("客户%d进来了,IP地址为%s,端口号为%d\n",fd,inet_ntoa(client.sin_addr),ntohs(client.sin_port));
            inet_ntoa(client.sin_addr) //网络二进制转回点分十进制
            ntohs(client.sin_port) //大端转小端

实例代码如下: 

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
struct sockaddr_in client;
int len = sizeof(client);
void *zhuanfa(void *arg)
{int ret;int fd = *(int *)arg;char buf[1024];//接信息char buf1[50] = "注意绿色上网!";while(1){bzero(buf,sizeof(buf));ret = recv(fd,buf,sizeof(buf),0);if(0 == ret){printf("客户%d离开了\n",fd);close(fd);return NULL;}else{printf("客户%d:%s\n",fd,buf); printf("客户%d进来了,IP地址为%s,端口号为%d\n",fd,inet_ntoa(client.sin_addr),ntohs(client.sin_port));send(fd,buf1,strlen(buf1),0); }	}return NULL;
}int main(void)
{//socketint serfd = socket(AF_INET,SOCK_STREAM,0);if(0>serfd){perror("socket");return -1;}//bindstruct sockaddr_in ser;//netinet/in.hser.sin_family = AF_INET;ser.sin_port = htons(8888);ser.sin_addr.s_addr = inet_addr("192.168.10.5");if(bind(serfd,(struct sockaddr *)&ser,sizeof(ser))<0){perror("bind");return -1;}	//listenlisten(serfd,8);//acceptint cfd;pthread_t a;while(1){//不断接受不同的客户端,并分配一个服务员给客户对接,在线程进行通信cfd = accept(serfd,(struct sockaddr *)&client,&len);//accept保存客户信息到clientpthread_create(&a,NULL,zhuanfa,&cfd);pthread_detach(a);}return 0;
}

二、域通信

优点:没网情况下照样能用客户端与服务器代码测试,模仿TCP/UDP
局限性:不能跨主机,只用于网络环境苛刻下的代码测试
区别:
                域通信:
                    struct sockaddr_un        <sys/un.h>
                        struct sockaddr_un{
                            sa_family_t   sin_family;   //地址族
                            char     sun_path[108];      //s套接字的路径千万要用strcpy赋值
                        };
                    s套接字,在bind后运行执行文件它就出现

域通信TCP实例代码如下: 

服务器:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
#include <sys/select.h>
int main(void)
{//socket(变动)int sockfd = socket(AF_UNIX,SOCK_STREAM,0);//注意AF_UNIXif(0>sockfd){perror("socket");return -1;}//bind(变动)struct sockaddr_un server;server.sun_family = AF_UNIX;strcpy(server.sun_path,"DJ");bind(sockfd,(struct sockaddr *)&server,sizeof(server));//listenlisten(sockfd,8);//多路复用selectint max = 0;int ret,cfd;//标志fd_set rfds;//读集合char buf[30];while(1){FD_ZERO(&rfds);FD_SET(0,&rfds);FD_SET(sockfd,&rfds);max = sockfd;if(cfd>sockfd)//第一遍还没连接,这个判断没有作用{max=cfd;FD_SET(cfd,&rfds);}select(max+1,&rfds,NULL,NULL,NULL);if(FD_ISSET(0,&rfds)){bzero(buf,sizeof(buf));printf("0文件描述符触发\n");scanf("%s",buf);printf("键盘输入:%s\n",buf);if(cfd>3)//说明有人连接,改变了cfd一开始的值{send(cfd,buf,strlen(buf),0);}}else if(FD_ISSET(sockfd,&rfds)){cfd = accept(sockfd,NULL,NULL);if(0>cfd){perror("accept");return -1;}printf("有客户连接进来了!\n");}else{bzero(buf,sizeof(buf));ret = recv(cfd,buf,sizeof(buf),0);if(0 == ret){perror("recv");return -1; }else{printf("客户说:%s\n",buf);} }}return 0;
}

客户端:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
void *(recv_msg)(void *arg)
{int ret;int fd = *(int *)arg;char buf[50];while(1){bzero(buf,sizeof(buf));ret = recv(fd,buf,sizeof(buf),0);if(0>ret){perror("recv");return NULL;}else if(0 == ret){printf("服务器离开了\n");return NULL;}elseprintf("服务器说:%s\n",buf);}return NULL;
}
int main(int argc,char *argv[])
{//变量区int clifd,ret;char buf[1024];pthread_t pid;//1>进行传参错误判断if(argc<2)//你运行时输入的个数   ./x a b {printf("请输入<./可执行> <S_name> \n");	return -1;}//2>创建socket套接字clifd = socket(AF_UNIX,SOCK_STREAM,0);if(clifd<0){perror("socket");return -1;}printf("创建出的socket的值为%d\n",clifd);//3>声明s套接字struct sockaddr_un server;server.sun_family = AF_UNIX;strcpy(server.sun_path,(argv[1]));
#if 0if(bind(clifd,(struct sockaddr *)&server,sizeof(server))<0){perror("bind");return -1;}//4>监听if(listen(clifd,8)<0){perror("listen");return -1;}printf("监听已启动,保护服务器中^-^\n");
#endif//5>主动连接服务器if(connect(clifd,(struct sockaddr *)&server,sizeof(server))<0){perror("connect");return -1;}printf("成功连接!\n");//开辟线程pthread_create(&pid,NULL,recv_msg,&clifd);pthread_detach(pid);//6>收发数据while(1){bzero(buf,sizeof(buf));scanf("%s",buf);send(clifd,buf,strlen(buf),0);}//7>关闭套接字close(clifd);return 0;
}

补充说明: 

 注意:如果bind的错误提示,说地址已经占用
                    就用remove();清掉自己绑定的s套接字,再运行就没有
                    AF_UNIX 
                        进程间通信有七种
                            早期:
                                1>无名管道
                                2>有名管道
                                3>信号
                            系统:
                                4>消息队列
                                5>共享内存
                                6>信号量
                            网络编程:
                                7>s套接字
                正常:
                    struct sockaddr_in
                    网络属性(IP地址和端口号)
                    AF_INET

三、广播与组播(UDP) 

1.广播

          看图
        允许发送的广播的属性怎么设置
            #include<sys/types.h>
            #include<sys/socket.h>
            setsockopt
                int setsockopt(int sockfd,int level,int optname,const void * optval,socklen_t optlen);
                功能:
                    设置套接字的属性
                参数:
                    sockfd:套接字
                    level:等级
                    optname:属性名字
                    optval:属性的值
                    optlen:属性的长度
                返回值:
                    成功为0
                    失败返回-1,并设置错误码
            举例:
                1>允许发送的广播的属性
                int on = 1;//1>为生效值,0>不生效
                setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
                2>允许重复用
                int on = 1;//1>为生效值,0>不生效
                setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) 

实例代码如下: 

sendto:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
int main(void)
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(0>sockfd){perror("socket");return -1;}//设置发送广播属性int on = 1;//1>为生效值,0>不生效setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));struct sockaddr_in gb;gb.sin_family = AF_INET;gb.sin_port = htons(10086);gb.sin_addr.s_addr = inet_addr("192.168.10.255");
#if 0if(bind(sockfd,(struct sockaddr *)&gb,sizeof(gb))<0){perror("bind");return -1;}
#endif	char buf[1024];// int addrlen = sizeof(gb);while(1){bzero(buf,sizeof(buf));scanf("%s",buf);sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&gb,sizeof(gb));// printf("广播:%s\n",buf);}return 0;
}

 recvfrom:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
int main(void)
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);if(0>sockfd){perror("socket");return -1;}struct sockaddr_in gb;gb.sin_family = AF_INET;gb.sin_port = htons(10086);gb.sin_addr.s_addr = inet_addr("192.168.10.255");if(bind(sockfd,(struct sockaddr *)&gb,sizeof(gb))<0){perror("bind");return -1;}char buf[1024];int addrlen = sizeof(gb);while(1){bzero(buf,sizeof(buf));recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&gb,&addrlen);printf("广播:%s\n",buf);}return 0;
}

 2.组播 

特定的广播,进一步细化成员
            看图
            多播组只有一个人,为单播;人多,就多播。
            
            optval,————》ip-mreq{}     //与stuct sockaddr_in一个头文件netinet/in.h
            struct ip_mreq 
            {
                 struct  in_addr  imr_multiaddr;    //    组播地址    
                 struct  in_addr  imr_interface;    //自己linux的ip地址
            };
            struct in_addr{
                In_addr_t  s_addr;    //32位IPv4地址
            };
            举例:加入多播组
            struct ip_mreq zb;
            zb.imr_multiaddr.s_addr = inet_addr("233.233.233.233");
            zb.imr_interface.s_addr = inet_addr("192.168.10.5");
            setsockopt(sockfd,IPPROTO_IP,SO_ADD_MEMBERSHIP,&zb,sizeof(zb)); 

实例代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
int main(void)
{//1.socketint sockfd = socket(AF_INET,SOCK_DGRAM,0);if(0>sockfd){perror("socket");return -1;}//2.运行发送广播int on = 1;//1>为生效值,0>不生效setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));//3.声明组播地址struct sockaddr_in zb;zb.sin_family = AF_INET;zb.sin_port = htons(9898);zb.sin_addr.s_addr = inet_addr("233.233.233.233");// if(bind(sockfd,(struct sockaddr *)&zb,sizeof(zb))<0)// {// perror("bind");// return -1;	// }//3.加入多播组// struct ip_mreq zb;// zb.imr_multiaddr.s_addr = inet_addr("233.233.233.233");// zb.imr_interface.s_addr = inet_addr("192.168.10.5");// setsockopt(sockfd,IPPROTO_IP,SO_ADD_MEMBERSHIP,&zb,sizeof(zb));//4.接收数据char buf[30];// int len = sizeof(zb);while(1){bzero(buf,sizeof(buf));scanf("%s",buf);sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&zb,sizeof(zb));// printf("S:%s\n",buf);}return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
int main(void)
{//1.socketint sockfd = socket(AF_INET,SOCK_DGRAM,0);if(0>sockfd){perror("socket");return -1;}//2.bind组播地址struct sockaddr_in zb;zb.sin_family = AF_INET;zb.sin_port = htons(9898);zb.sin_addr.s_addr = inet_addr("233.233.233.233");if(bind(sockfd,(struct sockaddr *)&zb,sizeof(zb))<0){perror("bind");return -1;	}//3.加入多播组struct ip_mreq db;db.imr_multiaddr.s_addr = inet_addr("233.233.233.233");db.imr_interface.s_addr = inet_addr("192.168.10.5");setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&db,sizeof(db));//4.接收数据char buf[30];int len = sizeof(zb);while(1){bzero(buf,sizeof(buf));recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&zb,&len);printf("S:%s\n",buf);}return 0;
}

四、图解如下

 

 


 总结

关于C/C++网络编程基础知识超详细讲解第二部分的详解,懒大王就先分享到这里了,如果你认为这篇文章对你有帮助,请给懒大王点个赞点个关注吧,如果发现什么问题,欢迎评论区留言!!💕💕 💕 

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

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

相关文章

《向量数据库指南》——开源框架NVIDIA Merlin 向量数据库Milvus

NVIDIA Merlin & Milvus 推荐系统 pipeline 中至关重要的一环便是为用户检索并找到最相关的商品。为了实现这一目标,通常会使用低维向量(embedding)表示商品,使用数据库存储及索引数据,最终对数据库中数据进行近似最近邻(ANN)搜索。这些向量表示是通过深度学习模型获…

STM32单片机在线升级,手机在线升级STM32单片机,固件远程下载方法,局域网在线程序下载

STM32单片机&#xff0c;是我们最常见的一种MCU。通常我们在使用STM32单片机都会遇到程序在线升级下载的问题。 STM32单片机的在线下载通常需要以下几种方式完成&#xff1a; 1、使用ST提供的串口下载工具&#xff0c;本地完成固件的升级下载。 2、自行完成系统BootLoader的编写…

使用阿里云服务器,httplib库在listen过程中,出现Cannot assign requested address错误???

今天&#xff0c;在做一个小项目的时候&#xff0c;使用httplib库进行建立tcp连接&#xff0c;但是一旦程序开始&#xff0c;并没有等待tcp连接的到来&#xff0c;而是直接结束了。 打印一下strerror(errno) 根本就没有进行客户端的连接。 找了一下午&#xff0c;检测是否…

大数据毕业设计选题推荐-收视点播数据分析-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT研究室✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

javaee实验:搭建maven+spring boot开发环境,开发“Hello,Spring Boot”应用

目录 mavenspringboot实验目的实验内容环境的搭建 在开发中&#xff0c;maven和spring都是非常常用、非常重要的管理工具和框架&#xff0c;今天就在这里使用idea进行环境的搭建和创建第一个spring程序 maven 1.1maven是一个跨平台的项目管理工具&#xff08;主要管理jar包&am…

【双指针+简化去重操作】Leetcode 15 三数之和

【双指针简化操作】Leetcode 15 三数之和 解法1 解法1 新建一个嵌套列表&#xff1a;List<List<Integer>> result new List<>(); 初始化一个ArrayList并直接赋值&#xff1a;ArrayList<Integer> result new ArrayList<>(Arrays.asList(1, 2…

Python库学习(十二):数据分析Pandas[下篇]

接着上篇《Python库学习(十一):数据分析Pandas[上篇]》,继续学习Pandas 1.数据过滤 在数据处理中&#xff0c;我们经常会对数据进行过滤&#xff0c;为此Pandas中提供mask()和where()两个函数&#xff1b; mask(): 在 满足条件的情况下替换数据&#xff0c;而不满足条件的部分…

Find My手机保护壳|苹果Find My与手机保护壳结合,智能防丢,全球定位

随着科技水平的快速发展&#xff0c;科技美容这一行业做为新型产业新生而出。时尚IT品牌随着市场的多元化发展。针对手机品牌和功能的增加而呈多样化&#xff0c;将手机保护壳按质地分有PC壳&#xff0c;皮革 &#xff0c;硅胶&#xff0c;布料&#xff0c;硬塑&#xff0c;皮套…

mac电脑大旧型文件清理软件CleanMyMac2024

CleanMyMac的大旧文件模块会帮您定位、检查和移除您几个月没有打开过并且不再需要的大型文件和文件夹&#xff0c;这样可以节省更多的磁盘空间。 CleanMyMac X全新版下载如下: https://wm.makeding.com/iclk/?zoneid49983 大型和旧文件模块可以查找和移除大型文件和文件夹&…

Python 海龟绘图基础教学教案(六)

Python 海龟绘图——第 9 题 题目&#xff1a;绘制下面的图形 解析&#xff1a; 综合应用&#xff0c;绘制长方形。 答案&#xff1a; 不使用循环。 Python 海龟绘图——第 10 题 题目&#xff1a;绘制下面的图形 解析&#xff1a; 综合命令使用。 答案&#xff1a; 使用循环…

Java VMTranslator Part II

用Java写一个翻译器&#xff0c;将Java的字节码翻译成汇编语言 目录 程序控制流开发 基本思路 核心代码 实验结果&#xff0c;使用例子进行验证 函数调用 基本思路 核心代码 实验结果&#xff0c;使用例子进行验证 Parser CodeWriter Main 程序控制流开发 基本思路…

2.JMeter压测接口

概述 今日目标&#xff1a; JMeter使用 配置线程组配置 HTTP 接口配置断言 配置响应断言配置断言响应时间 配置结果监听压测报告 接口准备聚合报告察看结果树其它 线程组配置详解 线程数Ramp-Up bug结束 JMeter使用 双击 ApacheJMeter.jar 启动&#xff0c;然后修改名称&a…

C 练习实例10 打印楼梯,同时在楼梯上方打印两个笑脸。

题目&#xff1a;打印楼梯&#xff0c;同时在楼梯上方打印两个笑脸。 程序分析&#xff1a;用 ASCII 1 来输出笑脸&#xff1b;用i控制行&#xff0c;j来控制列&#xff0c;j根据i的变化来控制输出黑方格的个数。 如果出现乱码情况请参考【C 练习实例7】的解决方法。 实例 …

第四届辽宁省大学生程序设计竞赛(正式赛)(12/13)

AC情况 赛中通过赛后通过暂未通过A√B√C√D○E○F√G√H√I○J√K—L√M√ 整体体验 easy&#xff1a;ABFHL mid&#xff1a;MJGC hard&#xff1a;IDKE 心得 感觉出了一堆典题&#xff0c;少数题还有些意思&#xff0c;E题确实神仙 题解 A. 欢迎来到辽宁省赛&#x…

iphone15 nplayer播放本地电影投屏天猫魔盒(电视)卡顿解决方案

文章目录 投屏环境现象写在前面 解决方案所需投屏app安装方法试用结果如果文章对您有用&#xff0c;欢迎收藏或关注&#xff01; iphone15 nplayer播放本地电影投屏天猫魔盒(电视)卡顿解决方案 投屏环境 全千兆wifi6局域网 1000兆电信宽带 天锚魔盒4Pro 8G&#xff08;M19&…

《研发效能(DevOps)工程师》课程简介(四)丨IDCF

由国家工业和信息化部教育与考试中心颁发的职业技术证书&#xff0c;也是国内首个研发效能&#xff08;DevOps&#xff09;职业技术认证&#xff0c;内涵1000页学习教材2000分钟的课程内容讲解460多个技术知识点300多道练习题。涵盖【组织与协作】、【产品设计与运营】、【开发…

YOLOv8-Seg改进:动态蛇形卷积(Dynamic Snake Convolution) | ICCV2023

🚀🚀🚀本文改进:动态蛇形卷积(Dynamic Snake Convolution),增强微小特征提取能力,引入到YOLOv8-Seg,与C2f结合实现二次创新 🚀🚀🚀Dynamic Snake Convolution亲测在番薯破损分割任务中,mask mAP@0.5 从原始的0.625提升至0.645 🚀🚀🚀YOLOv8-seg创新专…

namespace

1.namespace技术 namespace是Linux内核的一组特性&#xff0c;支持对内核资源进行分区隔离&#xff0c;让一组进程只能看到一组资源&#xff0c;而另一组进程只能看到另一组不同的资源。换句话说&#xff0c;namespace的关键特性是进程隔离。在运行许多不同服务的服务器上&…

2023.11.4 Idea 配置国内 Maven 源

目录 配置国内 Maven 源 重新下载 jar 包 配置国内 Maven 源 <mirror><id>alimaven</id><name>aliyun maven</name><url>http://maven.aliyun.com/nexus/content/groups/public/</url><mirrorOf>central</mirrorOf> …

chrome 扩展 popup 弹窗的使用

popup的基本使用方法 popup介绍 popup 是点击 browser_action 或者 page_action图标时打开的一个小窗口网页&#xff0c;焦点离开网页就立即关闭&#xff0c;一般用来做一些临时性的交互。 popup配置 V3版本中&#xff08;V2版本是在 browser_action 中 &#xff09;&#x…