网络编程 总结三

news2024/10/7 20:33:53

一、并发服务器模型

【1】 循环服务器

1>一次只能处理一个客户端的请求,等待这个客户端退出后,才能处理下一个客户端

2>缺点:循环服务器所处理的客户端不能有耗时操作

//*****模型******

sfd = socket();
bind();
listen();
while(1)
{
    newfd = accept();
    while(1)
    {
        recv();
        send();
    }
    close(newfd);
}
close(sfd);

【2】并发服务器

1>可以同时处理多个客户端请求

2>父进程 / 主线程专门用于负责连接,创建子进程 / 分支线程用来与客户端交互

~多线程:

//*****模型******

sfd = socket();
bind();
listen();
while(1)
{
    newfd = accept();

    pthread_create();

    pthread_detach(tid);

}

close(sfd);

void * callBack(void * arg)

{

      recv();
      send();
      close(newfd);

      pthread_exit(NULL);
}

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<sys/wait.h>
#include<signal.h>
#include<stdlib.h>
#include<pthread.h>

#define ERR_MSG(msg) do{\
	fprintf(stderr,"liine %d",__LINE__);\
	perror(msg);\
}while(0)

#define IP "192.168.0.79"  //本机IP 
#define PORT 6666          // 1024-49151

void* deal_cli_msg(void *arg);
//需要传递给线程处理函数的参数
struct cli_msg
{
	int newfd;
	struct sockaddr_in cin;
};

int main(int argc, const char *argv[])
{
	//创建流式套接字
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		ERR_MSG("socket");
		return -1;
	}
	printf("sfd=%d\n",sfd);
	//允许端口快速重用
	int reuse=1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
	//填充地址信息结构体
	//真是的地址信息结构体根据地址族制定  AF_INET: man 7 ip
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;//必须填 AF_INET
	sin.sin_port = htons(PORT);//端口号, 1024-49151
	sin.sin_addr.s_addr = inet_addr(IP);//本机IP,ifconfig
	//将IP和端口号绑定到套接字上
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind sucess __%d__\n",__LINE__);

	//将套接字设置为被动监听状态,监听是否有客户端连接成功
	if(listen(sfd,128)<0)
	{
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success __%d__\n",__LINE__);
	struct sockaddr_in cin;        // 存储连接成功的客户端地址信息  
	socklen_t addrlen = sizeof(cin);
	
	pthread_t tid;
	int newfd=-1;
	struct cli_msg info;
	while(1)
	{
		//阻塞函数,从已完成连接的队列头中获取一个客户端信息
		//该文件描述符才是与客户端通信的文件描述符
		newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);
		if(newfd<0)
		{
			ERR_MSG("accept");
			return -1;
		}
		printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
			inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);
		
		info.newfd=newfd;
		info.cin=cin;
		//能运行到当前位置
		if(pthread_create(&tid,NULL,deal_cli_msg,&info)!=0)
		{
			fprintf(stderr,"line:%d pthread_createfailed\n",__LINE__);
			return -1;
		}
		pthread_detach(tid); //分离线程
	}
	close(sfd);
	return 0;
}

void* deal_cli_msg(void *arg)
{
	int newfd=((struct cli_msg*)arg)->newfd;
	struct sockaddr_in cin=((struct cli_msg*)arg)->cin;
	char buf[128]="";
	ssize_t res=0;
	while(1)
	{
		//接收
		res=recv(newfd,buf,sizeof(buf),0);
		if(res<0)
		{
			ERR_MSG("recv");
			break;
		}
		else if(0==res)
		{
			printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
			inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);
			break;
		}
		printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
			inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);
		//发送
		strcat(buf,"*_*");
		if(send(newfd,buf,sizeof(buf),0)<0)
		{
			ERR_MSG("send");
			break;
		}
		printf("send sucess\n");
	}
	close(newfd);
	pthread_exit(NULL);
}

二、IO模型

【1】阻塞IO

创建套接字文件描述符后,默认处于阻塞IO模式 (read, write, recv, send, recvfrom, sendto)

【2】阻塞IO

1>防止进程阻塞在IO函数上,但是如果想要获取到有效数据,需要轮询

2>当一个程序使用了非阻塞IO模式的套接字,那么它需要使用一个循环来不停地判断该文件描述符是否有数据可读,称之为 polling

3>应用程序不停地polling 内核监测IO 事件是否产生, CPU消耗高

1)fcntl 函数

 【3】信号驱动IO

1>异步通信方式

2>信号驱动IO是指:预先告诉内核,某个文件描述符发生IO事件的时候,内核会通知相关进程: SIGIO

3> 对于TCP而言,信号驱动IO对TCP没有用,因为信号产生过于频繁,而且不能区分是哪个文件描述符发送的

【4】IO 多路复用(重点)

1>进程中如果同时需要处理多路输入输出流,在使用单进程单线程的情况下,同时处理多个输入输出请求

2>在无法用多进程多线程,可以选择用IO多路复用

3>由于不需要创建建新的进程和线程,减少系统的资源开销,减少上下文切换的次数

4>允许同时对多个IO进行操作,内核一旦发现进程执行一个或多个IO 事件,会通知该进程。

1)select  

 模型:

 代码:

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

#define ERR_MSG(msg) do{\
	fprintf(stderr,"liine %d",__LINE__);\
	perror(msg);\
}while(0)

#define IP "192.168.0.211"  //本机IP 
#define PORT 6666          // 1024-49151

int main(int argc, const char *argv[])
{
	//创建流式套接字
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind sucess __%d__\n",__LINE__);

	//允许端口快速使用
	int reuse=-1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
	{
		ERR_MSG("setsockopt");
		return -1;
	}
	printf("允许端口快速重用成功\n");

	struct sockaddr_in sin;
	sin.sin_family =AF_INET;
	sin.sin_port=htons(PORT);//端口号
	sin.sin_addr.s_addr=inet_addr(IP);//本机号

	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind sucess__%d__\n",__LINE__);

	//将套接字设置为被动监听状态,监听是否有客户端连接成功
	if(listen(sfd,128)<0)
	{
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success __%d__\n",__LINE__);

	//设置一个读集合
	fd_set  readfds,tmpfds;

	//由于readfds中需要防止要检测的文件描述符,所以不能让他是随机值
	//所以需要将readfds清空
	FD_ZERO(&readfds);
	FD_ZERO(&tmpfds);

	//将需要的文件描述符添加到集合中
	FD_SET(0,&readfds);
	FD_SET(sfd,&readfds);

	int s_res=0;
	char buf[128]="";
	struct sockaddr_in cin;        // 存储连接成功的客户端地址信息  
	socklen_t addrlen = sizeof(cin);

	struct sockaddr_in saveCin[1024-4];//另存客户端地址信息,0,1,2,sfd不可能有对应的客户端
	int newfd =-1;
	ssize_t res=0;
	int maxfd=sfd;//最大文件描述符

	while(1)
	{
		tmpfds=readfds;
		s_res=select(maxfd+1,&tmpfds,NULL,NULL,NULL);
		if(s_res<0)
		{
			ERR_MSG("select");
			return -1;
		}
		else if(0==res)
		{
			printf("time out\n");
			return -1;
		}

		//能运行到当前位置,则代表有文件描述符准备就绪
		//走触发事件的文件描述符对应的处理函数

		//当前集合中有文件描述符准备就绪了
		//当准备就绪,集合会只保留0
		//当sfd准备就绪,集合就会只保留sfd
		//当0和sfd都准备就绪,集合中保留0和sfd

		for(int i=0;i<=maxfd;i++)
		{
			if(!FD_ISSET(i,&tmpfds))//如果不在集合中,则直接往后继续变量
			{
				continue;
			}
			//能运行到当前位置,则说明i代表的文件描述符在tmpfds中
			//要判断i所代表的文件描述符需要走什么对应的函数
			if(0==i)
			{
				printf("触发键盘输入事件>>");
				int sndfd=-1;
				res=scanf("%d %s",&sndfd,buf);
				while(getchar()!=10);
				if(res!=2)
				{
					fprintf(stderr,"请输入正确格式:int string\n");
					continue;
				}
				//能运行到当前位置,则代表输入的格式整数
				if(sndfd<=sfd||sndfd>=1024||!FD_ISSET(sndfd,&readfds))
				{
					fprintf(stderr,"sndfd=%d文件描述符\n",sndfd);
					continue;
				}
				if(send(sndfd,buf,sizeof(buf),0)<0)
				{
					ERR_MSG("send");
					return -1;
				}
			}
			else if(sfd==i)
			{	
				printf("触发客户端连接事件>>");
				fflush(stdout);
				int newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);
				if(newfd<0)
				{
					ERR_MSG("accept");
					return -1;
				}
				printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
						inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);

				saveCin[newfd-4]=cin;

				//将newfd添加到读集合中
				FD_SET(newfd,&readfds);

				//更新maxfd
				maxfd=maxfd>newfd?maxfd:newfd;

			}
			else
			{
				bzero(buf,sizeof(buf));
				//接收
				res=recv(i,buf,sizeof(buf),0);
				if(res<0)
				{
					ERR_MSG("recv");
					return -1;
				}
				else if(0==res)
				{
					printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
							inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);

					//关闭文件描述符
					close(i);
					//从集合中剔除该文件描述符
					FD_CLR(i,&readfds);

					//更新maxfd
					//从目前最大的文件描述符中往小的判断
					int j=0;
					for(int j=maxfd;j>=0;j--)
					{
						if(FD_ISSET(j,&readfds))
						{
							maxfd=j;
							break;
						}
					}
					if(j<0)
						maxfd=-1;

					continue;
				}
				printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
						inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);

				strcat(buf,"*_*");
				if(send(i,buf,sizeof(buf),0)<0)
				{
					ERR_MSG("send");
					return -1;
				}
				printf("send sucess\n");
			}
		}
	}
	close(sfd);
	return 0;
}

2)poll

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<sys/time.h>
#include<sys/select.h>
#include<poll.h>

#define ERR_MSG(msg) do{\
	fprintf(stderr,"liine %d",__LINE__);\
	perror(msg);\
}while(0)

#define IP "192.168.0.211"  //本机IP 
#define PORT 6666          // 1024-49151

int main(int argc, const char *argv[])
{
	//创建流式套接字
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd<0)
	{
		ERR_MSG("bind");
		return -1;
	}
	printf("bind sucess __%d__\n",__LINE__);

	//将套接字设置为被动监听状态,监听是否有客户端连接成功
	if(listen(sfd,128)<0)
	{
		ERR_MSG("listen");
		return -1;
	}
	printf("listen success __%d__\n",__LINE__);

	//设置一个读集合
	fd_set  readfds,tmpfds;

	//由于readfds中需要防止要检测的文件描述符,所以不能让他是随机值
	//所以需要将readfds清空
	FD_ZERO(&readfds);
	FD_ZERO(&tmpfds);

	//将需要的文件描述符添加到集合中
	FD_SET(0,&readfds);
	FD_SET(sfd,&readfds);

	int s_res=0;
	char buf[128]="";
	struct sockaddr_in cin;        // 存储连接成功的客户端地址信息  
	socklen_t addrlen = sizeof(cin);

	int newfd =-1;
	ssize_t res=-1;
	int maxfd=sfd;

	while(1)
	{
		
		tmpfds=readfds;
		s_res=select(maxfd+1,&tmpfds,NULL,NULL,NULL);
		if(s_res<0)
		{
			ERR_MSG("select");
			return -1;
		}
		if(0==res)
		{
			printf("time out\n");
			return -1;
		}
		
		//能运行到当前位置,则代表有文件描述符准备就绪
		//走触发事件的文件描述符对应的处理函数

		for(int i=0;i<=maxfd;i++)
		{
			if(!FD_ISSET(i,&tmpfds))//如果不在集合中,则直接往后继续变量
			{
				continue;
			}
		//能运行到当前位置,则说明i代表的文件描述符在tmpfds中
		//要判断i所代表的文件描述符需要走什么对应的函数
			if(0==i)
			{
				printf("触发键盘输入事件>>");
				fgets(buf,sizeof(buf),stdin);
				buf[strlen(buf)-1]=0;
				printf("%s\n",buf);
			}
			else if(sfd==1)
			{	
				printf("触发客户端连接事件>>");
				fflush(stdout);
				int newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);
				if(newfd<0)
				{
					ERR_MSG("accept");
					return -1;
				}
				printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
					inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);
	
				//将newfd添加到读集合中
				FD_SET(newfd,&readfds);

				//更新maxfd
				maxfd=maxfd>newfd?maxfd:newfd;

			}
			else
			{
				bzero(buf,sizeof(buf));
			//接收
				res=recv(i,buf,sizeof(buf),0);
				if(res<0)
				{
					ERR_MSG("recv");
					return -1;
				}
				else if(0==res)
				{
					printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
						inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);
				
					//关闭文件描述符
					close(i);
					//从集合中剔除该文件描述符
					FD_CLR(i,&readfds);
				
					//更新maxfd
					//从目前最大的文件描述符中往小的判断
					int j=0;
					for(int j=maxfd;j>=0;j--)
					{
						if(FD_ISSET(j,&readfds))
						{
							maxfd=j;
							break;
						}
					}
					if(j<0)
						maxfd=-1;

					continue;
				}
				printf("[%s:%d] newfd=%d 连接成功 __%d__\n",\
					inet_ntoa(cin.sin_addr),ntohs(cin.sin_port), newfd,__LINE__);

				strcat(buf,"*_*");
				if(send(i,buf,sizeof(buf),0)<0)
				{
					ERR_MSG("send");
					return -1;
				}
				printf("send sucess\n");
			}
		}
	}
	return 0;
}

三、函数库

【1】库的概念

1>库是一个二进制可执行文件,相比较于二进制可执行程序,库是不能单独运行的。

        a. 库中存放的都是功能函数,只能放功能函数

        b. 库中不允许存放main函数

        c.库是写好的,可以被服用的功能代码

2>库需要被载入到内存中使用

3>每个操作系统都有自己得库,不兼容

库的分类:

静态库、动态库

 【2】静态库

1)静态库原理:通过静态库封装的函数,在程序编译到链接库步骤的时候,会将函数继承到可执行程序中。

优点: 1>程序运行的时候,与静态库没有任何关系,方便移植

            2>静态库的运行效率会更快

缺点:1>程序的更新部署比较麻烦

           2>大、存储的时候浪费磁盘空间,加载运行的时候浪费内存空间

2)静态库地 制作指令

 步骤:

1>分文件,将功能函数与主函数分离,func.c  main.c

2>给功能函数写头文件:func.h

3>将main.c 和 func.c 联合编译,测试分文件是否成功

4>用上述指令将func.c 封装成静态库

5>注意:libxxx.a  ,  xxx才是库的名字

3)静态库的使用

【3】动态库(共享库)

 1)动态库的原理:动态库把库函数的链接步骤推迟到程序运行的时候,当程序执行到库函数的时候,会去找动态库函数

1>如果在内存中不存在该动态库函数,则会将动态库函数加载到内存中执行

2>如果在内存中存在该动态库函数,则直接调用,不会加载第二份

3>所以内存中会仅存在一份动态库函数

优点:

1>小、存储的时候节省磁盘空间,运行的时候节省内存空间

2>程序的更新部署比较方便,不需要重新编译可执行程序

缺点:

1>程序运行的时候,如果没有找到动态库,则会导致程序崩溃,所以用动态库生成二进制程序移植性低

2>运行效率低

2)动态库的制作指令

  步骤:

1>分文件,将功能函数与主函数分离,func.c  main.c

2>给功能函数写头文件:func.h

3>将main.c 和 func.c 联合编译,测试分文件是否成功

4>用上述指令将func.c 封装成静态库

5>注意:libxxx.so  ,  xxx才是库的名字

3)动态库的使用

 4)动态库的环境变量配置

1> 将动态库移动到 / lib/或者 /usr/lib 目录下

        a. sudo mv ./libmyfunc.so /usr/lib/

        b. sudo mv libmyfunc.so/lib/

2>配置环境变量:LD_LIBRARY_PATH

 3>修改环境变刘昂的配置文件

        a. cd / ec/ld.so.conf.d/

        b. sudo touch my.conf   创建一个 .conf结尾的文件

        c. sudo vim my.conf

        d. 将动态库所在的文件夹的绝对路径填写进去,注意一行只能填写一个动态库的绝对路径

        e. 保存退出后,执行sudo ldconfig 刷新环境变量

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

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

相关文章

springboot websocket通信

目录 一、websocket是什么 二、实现websocket 2.1参考学习b站资料&#xff08;一定要看&#xff0c;前后端详细&#xff09; 2.2学习配套代码 一、websocket是什么 WebSocket_ohana&#xff01;的博客-CSDN博客 二、实现websocket 2.1参考学习b站资料&#xff08;一定要看…

4 异常机制--数组、切片、算法【Go语言教程】

4 异常机制–数组、切片、算法【Go语言教程】 1 异常机制 1.1 处理错误 Go 语言追求简洁优雅&#xff0c;所以&#xff0c;Go 语言不支持传统的 try…catch…finally 这种处理。Go 中引入的处理方式为&#xff1a;defer, panic, recover这几个异常的使用场景可以这么简单描述…

【小沐学Python】Python实现Web服务器(Flask框架扩展:Flask-Admin)

文章目录 1、简介1.1 flask1.2 flask-admin 2、安装2.1 安装库2.2 打印库版本 3、初始化4、添加独立视图&#xff08;BaseView&#xff09;4.1 管理接口索引页4.2 自定义视图 5、添加模型视图&#xff08;ModelView&#xff09;6、添加特殊视图6.1 Managing Files & Folder…

VS2019配置redis客户端的c++开发环境

目录 需要的开源库&#xff1a; 具体步骤&#xff1a; 遇到的问题&#xff1a; 1. 确保每个项目使用的配置解决方案管理器一样 2.CMAKE 的安装 3. 使用 CMAKE 的路径配置 4. redis 编译报错&#xff1a;jemalloc/jemalloc.h没有这个文件&#xff0c;或者找不到.dll 5. linux …

【Linux】初识Linux --指令Ⅰ

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法&#xff0c;Linux…感兴趣就关注我吧&#xff01;你定不会失望。 目录 1.ls 显示当前目录下的文件内内容2.pwd-显示用户当前所在的目录3.cd-改变工作目录。将当前工作目录改变到指定的目…

C++ STL-deque

deque&#xff1a;双端队列 目录 deque&#xff1a;双端队列 1、 基本介绍 2、使用方法 2.1、 头文件 2.2、 定义 2.3、 方法函数 3、排序 1、 基本介绍 首尾都可插入和删除的队列为双端队列。 deque容器是连续的空间&#xff0c;其他连续的行空间还有 array 和 vect…

E. Multihedgehog(多叉树找root节点)

Problem - E - Codeforces 有人给Ivan一个奇怪的生日礼物&#xff0c;这是一只刺猬 - 一个连通的无向图&#xff0c;其中一个顶点的度至少为3&#xff08;我们称其为中心&#xff09;&#xff0c;而所有其他顶点的度数均为1。Ivan认为刺猬太无聊了&#xff0c;决定自己制造k-多…

总结838

四月结束&#xff0c;五月来临。又到了月度总结与规划的时候了。 四月总结&#xff1a;高等数学原计划复习完18讲内容&#xff0c;刷完对应的习题。如今还剩三讲&#xff0c;本可以看完&#xff0c;但因为后面分专题了&#xff0c;还没确定是数1还是数2.所以耽搁了一下。英语原…

SG函数(博弈论)

一&#xff0c;定义 对于满足以下条件的公平二人游戏&#xff0c;均可以用sg函数&#xff08;暴搜&#xff09;获得答案 人数2人 两人交替进行合法操作&#xff0c;无法进行者LOSE对 于游戏的任意一种可能的局面&#xff0c;合法的操作集合只取决于这个局面的本身&#xff0c;…

掌握 Python 接口自动化测试理论,深度解读测试框架源码

目录&#xff1a;导读 引言 一、什么是接口测试、为什么要做接口测试 1、什么是接口测试 2、为什么要做接口测试 二、接口测试的流程 1、接口测试的流程 2、为什么要写测试用例 3、接口测试设计要点 三、python接口自动化-requests的应用 1、requests简介 2、reques…

Winform从入门到精通(37)——FolderBrowserDialog(史上最全)

文章目录 前言1、Name2、Description3、RootFolder4、SelectedPath5、ShowNewFolderButton前言 当需要获取一个可以通过用户自由选择路径的时候,这时候就需要FolderBrowserDialog控件 1、Name 获取FolderBrowserDialog对象 2、Description 用于指示对话框的描述,如下: …

Doris(22):Doris的函数—地理位置函数

1 ST_AsText(GEOMETRY geo) 将一个几何图形转化为WKT(Well Known Text)的表示形式 SELECT ST_AsText(ST_Point(24.7, 56.7)); 2 ST_Circle(DOUBLE center_lng, DOUBLE center_lat, DOUBLE radius) 将一个WKT(Well Known Text)转化为地球球面上的一个圆。其中center_lng表…

20230502 强化学习与反馈控制_利用自然决策方法设计最优自适应控制器

目录&#xff1a;强化学习与反馈控制_利用自然决策方法设计最优自适应控制器 总体介绍强化学习二级目录三级目录 总体介绍 本文描述了利用强化学习原理为离散和连续系统设计反馈控制器&#xff0c;该控制器结合了自适应控制和最优控制的特点。自适应控制和最优控制代表了设计反…

【ElasticSearch】EQL操作相关

文章目录 EQL操作基础语法数据准备数据窗口搜索统计符合条件的事件事件序列 安全检测数据准备查看数据导入情况获取 regsvr32 事件的计数检查命令行参数检查恶意脚本加载检查攻击成功可能性 EQL操作 EQL 的全名是 Event Query Language (EQL)。事件查询语言&#xff08;EQL&…

Meta财报预测:市场悲观情绪被过度放大,Meta股价未来将强势反弹

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 4月26日收盘后&#xff0c;Meta(META)将发布2023年第一季度财报。由于全球在线广告支出的减少给Meta这样的广告平台带来了很大的压力&#xff0c;市场对Meta的投资情绪非常悲观&#xff0c;华尔街分析师也预测&#xff0c;…

chatGPT免登录的版本哪里有啊

ChatGPT免费次数 Chat GPT 模型通常通过 API 或 SDK 的方式进行使用&#xff0c;并且有一定的免费使用次数或免费试用期&#xff0c;以便用户可以在部分场景下了解模型的性能和效果。但是&#xff0c;每个机器学习平台或服务商的免费使用次数和试用期都可能不同&#xff0c;您…

ChatGPT回复中断的原因-chatGPT国内中文版免费

ChatGPT回复中断怎么办啊 如果您使用ChatGPT时遇到了中断或错误&#xff0c;以下是一些可能有用的解决方案&#xff1a; 检查输入是否正常&#xff1a;输入文本是否符合语法规范和限制条件&#xff0c;例如输入文本长度是否超过了模型限制等等。如果输入不符合要求&#xff0c…

pikachu靶场-Unsafe Filedownload

不安全的文件下载 文件下载功能在很多web系统上都会出现&#xff0c;一般我们当点击下载链接&#xff0c;便会向后台发送一个下载请求&#xff0c;一般这个请求会包含一个需要下载的文件名称&#xff0c;后台在收到请求后 会开始执行下载代码&#xff0c;将该文件名对应的文件…

Mysql数据库基础知识总复习

前言 小亭子正在努力的学习编程&#xff0c;接下来将开启javaEE的学习~~ 分享的文章都是学习的笔记和感悟&#xff0c;如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话&#xff0c;烦请点赞关注支持一波, 感激不尽~~ 目录 数据库基础知识 数据&#xff0c;数据…

GPT是什么,GPT-4是什么

GPT是Generative Pre-trained Transformer的缩写&#xff0c;是一种人工智能语言模型。为了实现自然语言生成和文本补全等功能&#xff0c;通过训练大规模数据集&#xff0c;GPT模型可以预测某个词或文本的下一个可能的词或文本。GPT是由OpenAI团队推出的&#xff0c;目前已经推…