2024/03/19(网络编程·day5)

一、思维导图

二、selec函数实现TCP并发服务器

#include<myhead.h>#define SER_PORT 8888 	//服务器端口号
#define SER_IP "192.168.117.116" 	//服务器IP
int main(int argc, const char *argv[])
{//1、创建一个套接字int sfd = -1;sfd = socket(AF_INET,SOCK_STREAM,0);//参数1:表示创建的是网络通信的套接字//参数2:表示使用的是TCP通信协议//参数3:参数2指定了协议,参数3填0即可if(sfd == -1){perror("socket error");return -1;}printf("%d success sfd = %d\n",__LINE__,sfd);  //3//设置端口号快速重用int reuse = 1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1){perror("setsockopt error");return -1;}printf("端口号快速重用成功\n");//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;}printf("%d bind success\n",__LINE__);//3、将套接字设置成被监听状态if(listen(sfd,128) == -1){perror("listen error");return -1;}//4、阻塞等待客户端的连接请求int newfd = -1;//定义结构体变量接受客户端地址信息结构体struct sockaddr_in cin;//接收客户端信息结构体socklen_t addrlen = sizeof(cin);//接收客户端结构体大小char sbuf[128] = ""; //服务器输入数据内容//11、定义一个文件描述符集合fd_set readfds,tempfds;//22、将集合清空FD_ZERO(&readfds);//33、将要被检测的文件描述符放入集合FD_SET(0,&readfds);FD_SET(sfd,&readfds);int maxfd = sfd; //记录当前容器中的最大文件描述符struct sockaddr_in cin_arr[1024]; //存储客户端信息结构体while(1){//将readfds备份tempfds = readfds;int res = select(maxfd+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文件描述符触发了事件//判断sfd是否触发事件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;//将newfd放入readfds容器中参与检测FD_SET(newfd,&readfds);//可能要更新的maxfdif(newfd > maxfd){maxfd = newfd;}}//判断0号文件描述符是否触发事件else if(0 == i){fgets(sbuf,sizeof(sbuf),stdin); //终端输入sbuf[strlen(sbuf)-1] = 0;printf("触发了键盘输入事件:%s\n",sbuf);//将消息发送给所有客户端for(int i = 4;i<= maxfd;i++){send(i,sbuf,sizeof(sbuf),0);}printf("发送成功\n");}else{//说明某个客户端发来消息了,遍历所有客户端,判断是哪个发来的消息//5、收发数据char rbuf[128] = "";//接收客户端发送的信息//将容器清空bzero(rbuf,sizeof(rbuf));//memset(rbuf,0,sizeof(rbuf));//从套接字中读取数据int res = recv(i,rbuf,sizeof(rbuf)-1,0);if(res == 0){			printf("客户端已下线\n");//关闭与客户端通信的套接字close(i);//将当前文件描述符移除容器FD_CLR(i,&readfds);//可能要更新maxfdfor(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," <Got it>!");send(i,rbuf,strlen(rbuf),0);printf("回复成功\n");}}}//6、关闭服务器close(sfd);return 0;
}

三、poll函数实现TCP客户端

#include<myhead.h>#define SER_PORT 8888 	//服务器端口号
#define SER_IP "192.168.117.116" 	//服务器IP
#define CLI_PORT 9999 	//客户端端口号
#define CLI_IP "192.168.117.116" 	//客户端IPint main(int argc, const char *argv[])
{//1、创建一个套接字int cfd = -1;cfd = socket(AF_INET,SOCK_STREAM,0);//参数1:表示创建的是网络通信的套接字//参数2:表示使用的是TCP通信协议//参数3:参数2指定了协议,参数3填0即可if(cfd == -1){perror("socket error");return -1;}printf("%d success cfd = %d\n",__LINE__,cfd);  //3//设置端口号快速重用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); //IP地址//2.2绑定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;
}

四、select函数实现的TCP并发服务器连接poll函数实现的TCP客户端

五、模拟面试

TCP通信中的三次握手和四次挥手过

三次握手:
1、客户端向服务器发送同步序列编号(SYN)的数据包,表示请求建立连接,并选择一个初始序列号(ISN)。

2、服务器收到客户端的SYN请求后,会发送一个带有SYN和ACK标志的数据包作为应答,确认客户端的SYN,并选择自己的初始序列号,并对客户端的初始序列号进行确认。

3、客户端收到服务器的确认后,会发送一个带有ACK标志的数据包作为确认,表示连接建立成功。

四次挥手:

1、客户端已经发送完所有数据,想要关闭连接,于是发送一个带有FIN标志的数据包给服务器,表示不再发送数据。

2、服务器收到客户端的FIN后,会发送一个带有ACK标志的数据包作为确认,表示已收到关闭请求,但仍可以发送数据。

3、服务器发送完所有数据后,也想要关闭连接,于是发送一个带有FIN标志的数据包给客户端,表示不再发送数据。

4、客户端收到服务器的FIN后,会发送一个带有ACK标志的数据包作为确认,表示已收到关闭请求,连接终止。

并发和并行的区别

并发是指多个任务交替地快速执行,而并行是指多个任务同时执行


并发指的是系统具有同时处理多个任务的能力。在单处理器系统中,通过快速地在不同任务之间进行切换,使得似乎多个任务在几乎同时执行。在多处理器系统中,不同的处理器可以同时执行不同的任务,这也是一种并发。并发一般是通过时间片轮转或者事件驱动的方式实现的。


并行指的是系统真正同时执行多个任务。在单处理器系统中是不可能真正实现并行的,只能通过并发来模拟。但在多处理器系统中,多个处理器可以同时执行多个任务,这就是真正的并行。

阻寒IO和非阻塞IO的区别

阻塞 I/O 会导致程序在进行 I/O 操作时被挂起,而非阻塞 I/O 允许程序在等待 I/O 操作的同时继续执行其他任务

在阻塞 I/O 中,当程序发起一个 I/O 操作时,程序会被阻塞,直到操作完成才能继续执行后续代码。

非阻塞 I/O 允许程序在发起一个 I/O 操作后立即返回,而不会等待操作完成。程序可以继续执行后续代码,然后再通过轮询或者事件通知等方式来检查 I/O 操作是否完成,如果完成则处理结果,否则继续进行其他任务。

同步和异步的区别

同步是顺序执行的,需要等待上一个操作完成才能执行下一个操作;而异步则是并发执行的,可以同时进行多个操作,不需要等待每个操作的完成

在同步操作中,当一个操作被发起后,必须等待这个操作完成后才能继续执行后续的操作。

在异步操作中,当一个操作被发起后,不需要等待这个操作完成,可以继续执行后续的操作。

详细描述IO多路复用的原理

①将多个阻塞任务的文件描述符统一放入一个检测容器中。

②用一个阻塞函数进行管理。

③如果检测容器中有一个或者多个文件描述符对应的事件产生,就去解除阻塞,执行相应函数。

广播的相关内容

在IPv4网络中,广播地址通常是特定的IP地址,网络号+主机号全为1,表示向本地网络中的所有设备发送广播数据包。对发送端套接字设置为允许广播,发送端类似于UDP客户端,接收端类似于UDP服务器端。UDP广播的优点是简单直接,可以方便地向局域网中的所有设备发送消息。

组播的相关内容

组播地址是D类网络地址,需要对接收端设置加入多播组属性。

发送端类似于UDP的客户端,接收端类似于UDP的服务器端,实现的一对多的通信,不同于广播的是范围不同,只有加入多播组的主机才能通信了。

在使用套接字通信时,客户端就一定不需要绑
定操作吗
不一定,对于报式域套接字而言,如果客户端不绑定套接字文件,系统不会自动绑定,可以发送数据,但是服务器端不能向客户端发送消息。
目前学习的进程间通信方式有哪些套接字,共享内存,有名管道,无名管道,信号,信号灯集,消息队列
线程的同步互斥机制

线程的同步互斥机制是指在多线程环境中控制线程之间执行顺序和共享资源访问,以确保线程之间的协调和正确性

同步互斥机制:

互斥锁(Mutex)

互斥锁是最常见的同步机制之一,用于保护临界区(一次只允许一个线程访问的资源或代码段),确保同一时间只有一个线程可以访问被锁定的资源。当一个线程获得了互斥锁后,其他线程需要等待直到该线程释放锁

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

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

相关文章

软件设计师:03 - 数据库系统

一、数据模型的分类 1.1、概念数据模型 1.2、结构数据模型 1.3 真题 二、三级模式 概念模式对应的是基本表&#xff0c;概念模式也称为模式 外模式对应的是视图&#xff0c;也称用户模式或者子模式 内模式对应的是数据库里面的存储文件&#xff0c;也称存储模式 真题 三、两级…

VO、RVO、ORCA(动态避障)算法

碰撞锥&#xff08;碰撞区域&#xff09; 上上图中假设B物体处于静止状态&#xff0c;A物体沿着向量v1和v2移动&#xff0c;刚好能和B擦肩而过&#xff0c;不会发生碰撞&#xff1b;若V1和V2的夹角再小一点的话就一定会发生碰撞。此时会产生碰撞区域&#xff1a; 红线画出来…

蓝桥杯练习04学生成绩统计

学生成绩统计 介绍 随着大数据的发展&#xff0c;数据统计在很多应用中显得不可或缺&#xff0c;echarts作为一款基于JavaScript的数据可视化图表库&#xff0c;也成为了前端开发的必备技能&#xff0c;下面我们一起来用echarts开发一个学生数据统计的柱形图。 准备 开始答…

Vmware使用ubuntu报错空间不够

Vmware使用ubuntu报错空间不够 1.vmware修改2.进入镜像进行修改2.1需要下载GParted软件 1.vmware修改 这个需要把硬盘的大小进行扩展 2.进入镜像进行修改 2.1需要下载GParted软件

C++_回文串

目录 回文子串 最长回文子串 分割回文串 IV 分割回文串 II 最长回文子序列 让字符串成为回文串的最少插入次数 回文子串 647. 回文子串 思路&#xff0c;i j表示改范围内是否为回文串&#xff0c; ②倒着遍历是为了取出dp[i 1][j - 1] ③i j 只有一对&#xff0c;不会重复…

harmonyOS简介及背景

harmonyOS的场景模式18n: 1&#xff08;入口手机&#xff09;8&#xff08;电脑、VR、手环、iPad、智慧屏、&#xff09;–wifi—n(车载、智能家居等所有)harmonyOS不需要考虑软硬件的差异&#xff0c;是一个兼容N种的超级终端harmonyOS干了两件事&#xff1a; &#xff08;1&a…

施工升降机AI数人数识别摄像机

施工现场作为一个复杂的工作环境&#xff0c;在施工过程中通常会有大量的人员出入&#xff0c;为了确保施工安全和管理效率&#xff0c;近年来施工升降机AI数人数识别摄像机应运而生。 这种摄像机依靠先进的人工智能技术和摄像头设备&#xff0c;能够实时监测和识别施工升降机内…

AIGC——ComfyUI工作流搭建、导入与常用工作流下载

工作流 ComfyUI工作流是一个基于图形节点编辑器的工作流程&#xff0c;通过拖拽各种节点到画布上&#xff0c;连接节点之间的关系&#xff0c;构建从加载模型到生成图像的流程。每个节点代表一个与Stable Diffusion相关的模型或功能&#xff0c;节点之间通过连线传递图片信息。…

2390.从字符串中移除星号

题目&#xff1a;给你一个包含若干星号 * 的字符串 s 。 在一步操作中&#xff0c;你可以&#xff1a; 选中 s 中的一个星号。移除星号 左侧 最近的那个 非星号 字符&#xff0c;并移除该星号自身。 返回移除 所有 星号之后的字符串。 注意&#xff1a; 生成的输入保证总是…

如何对静态IP进行测试?静态IP有什么优点?

随着互联网的普及&#xff0c;越来越多的人开始使用动态IP进行上网。但是在某些情况下&#xff0c;我们可能需要使用静态IP进行测试或特定的网络设置。本文将介绍如何获取静态IP进行测试以及静态IP的优点。 一、如何获取静态IP进行测试&#xff1f; 1.联系ISP&#xff08;Int…

【JS】数组查重

码 /*** 数组查重* param {Array} arr 查重的数组* returns Array 返回不重复的数组 */ const noReArr arr > [...new Set(arr)]const a [12,12,3,4] console.log( noReArr(a) );效果图

031—pandas 读取解析实验室数据至DataFrame

前言 某个科研实验室在进行一项物理实现&#xff0c;实验仪器会输出一个 txt 文本的数据&#xff0c;研究人员需要从这个文本中将数据结构化才能进行进行统计分析。 在为个解析和分析过程中&#xff0c;他们选择了 Python 的 pandas 库来完成这些操作。我们今天来完成这这个 t…

使用AOP拦截全局请求并校验请求参数

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

【数据结构】猛猛干11道链表OJ(未完待续ing)

前言知识点 链表的调试技巧 int main() {struct ListNode* n1(struct ListNode*)malloc(sizeof(struct ListNode));assert(n1);struct ListNode* n2(struct ListNode*)malloc(sizeof(struct ListNode));assert(n2);struct ListNode* n3(struct ListNode*)malloc(sizeof(struc…

蓝桥杯 2023 省B 飞机降落

首先&#xff0c;这题要求的数据量比较少&#xff0c;我们可以考虑考虑暴力解法。 这题可能难在很多情况的考虑&#xff0c;比如说&#xff1a; 现在时间是10&#xff0c;有个飞机20才到&#xff0c;我们是可以干等10分钟。 #include <iostream> #include <…

对话奇酷网络董事长吴渔夫: 迟到的游戏公司会被AI浪潮卷入海底

“ 迟到的游戏公司会被无形的 AI 浪潮卷入海底。” 整理 | 梦婕 编辑 | 云舒 出品&#xff5c;极新 2024年3月4日&#xff0c;在极新与吴渔夫的对话中&#xff0c;吴渔夫多次呼吁“全力拥抱AI”。在这场AI浪潮中&#xff0c;作为中国网游的先锋&#xff0c;他带着 25 年“中…

【web前端】<meta>标签

meta元素可以提供有关页面的元信息&#xff08;meta-information&#xff09; meta标签位于文档的头部&#xff0c;是空元素 meta元素的属性 属性值描述http-equiv expires refresh X-UA-compatible 定义HTTP协议的头部元信息名称。其中&#xff0c;expires设置网页在缓存区的…

记录一下目前为止的算法成长

每日笔记 复习曲线 间隔1天、3天、7天、15天、30天&#xff0c;然后以一个月为周期复习 2023. 12. 24 一定要每天早中晚都要复习一下 早中午每段一两道, 而且一定要是同一个类型, 不然刷起来都没有意义 11.29 开始向着面试刷题跟进! 每天刷4题左右 ,一周之内一定要是统一类…

笔记本8代i5和台式机12代i5的性能比较

一、 台式机12代i5 二、笔记本8代i5 在多核性能上差不多是2.4倍&#xff0c;所以跑大一点的Matlab或者别的程序&#xff0c;用台式机&#xff0c;后边实验室能用上超多核服务器另说。

uniapp,导航栏(切换项)有多项,溢出采取左滑右滑的形式展示

一、实现效果 当有多项的导航&#xff0c;或者说切换项&#xff0c;超出页面的宽度&#xff0c;我们采取可滑动的方式比较好一些&#xff01;并且在页面右边加个遮罩&#xff0c;模拟最右边有渐变效果&#xff01; 二、实现代码 html代码&#xff1a; <!-- 头部导航栏 --…