Linux + 香橙派 + V4L2 + http 实现远程监控摄像头在网页端显示

项目场景:

项目需求,需要做一个基于边缘端的人脸识别远程监控摄像头并在网页前端展示 ,这里采用国产香橙派作为边缘计算终端,安装ubuntu系统,系统中采用v4l2接口对摄像头进行获取,当客户端通过网页进行请求时,服务器通过http服务的形式将一帧帧图像发送给客户端,只要一秒钟能够传送25帧左右,展示效果就是在网页端播放视频:


问题描述1

怎样从摄像头里面获取帧数据,这里我们将USB摄像头连接在开发板上:

 可以看到,确实是有video0这个摄像头,该摄像头就是外接的USB摄像头


解决方案1:

采用V4L2接口通过中断将内核状态读取到的数据映射到用户空间:

 以下代码是将内核空间与用户空间进行映射

for(int i = 0; i <4;i++) {
        mapbuffer.index = i;
        ret = ioctl(fd,VIDIOC_QUERYBUF,&mapbuffer); //从内核空间中查询一个空间作映射
        if (ret < 0)
        {
            perror("查询内核空间失败");
        }
        //映射到用户空间
        mptr[i] = (unsigned char *)mmap(NULL,mapbuffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,mapbuffer.m.offset);
        size[i] = mapbuffer.length; //保存映射长度用于后期释放
        //查询后通知内核已经放回
        ret = ioctl(fd,VIDIOC_QBUF,&mapbuffer);
        if (ret < 0)
        {
            perror("放回失败");
        }
    }

以下代码是通过中断获取内核态的数据,并在用户态对数据进行内存拷贝,即将数据拷贝到数组,方便其他线程进行数据处理和数据展示

struct v4l2_buffer readbuffer;
        readbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //每个结构体都需要设置type为这个参赛要记住
        ret = ioctl(fd,VIDIOC_DQBUF,&readbuffer);
        int read_len = mapbuffer.length;
        int send_len = 1024;
        //printf("%d \n",read_len);
        if (ret < 0)
         {
         perror("读取数据失败");
         }
        if(1)
        {
        void *ptr = mptr[readbuffer.index];
        memcpy(jpg_buff, ptr, readbuffer.length); 
}

问题描述2

在网页前端播放视频,首先视频是一帧帧图像组成的,这里我们每间隔一个短时间就发送一帧,同时http 客户端和服务端采用keep-live长连接形式。为了加快速度,这里我采用了两个线程,现成1读取视频,并将图像帧放在一个公共数组中,线程2将公共数组中的数据通过tcp传输发送给客户端。

同时,线程1和线程之间采用的是条件变量进行同步


解决方案2:

多线程共享全局变量加快视频读取速度和图像发送速度:

线程1

 pthread_mutex_lock(&lock);
        void *ptr = mptr[readbuffer.index];
        memcpy(jpg_buff, ptr, readbuffer.length);//将读取到的图像拷贝到字符数组       
        pthread_mutex_unlock(&lock);
        pthread_cond_signal(&hasNode);

线程2

pthread_cond_wait(&hasNode,&lock);
void *ppptr = jpg_buff;
pthread_mutex_unlock(&lock);

这里的jpg_buff是共享全局数组 


问题描述3

网页长连接设置问题

服务器端在返回报文头时,加上

"Content-Type:multipart/x-mixed-replace;

即表示当前连接是基于长连接


解决方案:

提示:这里填写该问题的具体解决方案:

下面是报文头的内容 

/*
HTTP长连接处理客户端请求
"HTTP/1.0 200 OK\r\n"
"Server: wbyq\r\n"
"Content-Type:multipart/x-mixed-replace;boundary=boundarydonotcross\r\n"
"\r\n"
"--boundarydonotcross\r\n"
*/

这是程序运行时的效果图:

需要在与开发板同一个局域网的终端上网址中键入:192.168.0.105:8080

其中192.168.0.105是开发板的ip地址 

 

最后附上总代码

#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <assert.h>
#include <fcntl.h>
#include <jpeglib.h>
#include <linux/fb.h>
#include <linux/videodev2.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <pthread.h>
#include "sd_usb_pic.h"
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/types.h>          /* See NOTES */
#include <unistd.h>
#include <sys/time.h>

#define HTTP_PORT 8080   //HTTP服务器端口号
pthread_mutex_t mutex;
pthread_cond_t hasNode = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
char jpg_buff[614400]; //保存从USB摄像头读取的图像矩阵
int send_html_cnt = 0 ;
/*
服务端响应客户端请求

"HTTP/1.1 200 OK\r\n"
"Content-type:image/jpeg\r\n"
"Content-Length:1234\r\n"
"\r\n"

形参:c_fd  --客户端套接字
      type  --文件类型
	  file  --要发送的文件
返回值:0成功,其它失败
*/
void *ppp_tr = NULL;
int fd_fb;                                                    
static struct fb_var_screeninfo var; /* LCD可变参数 */
static unsigned int *fb_base = NULL; /* Framebuffer映射基地址 */                    
int lcd_w = 800 ,lcd_h= 480; //定义显示器分辨率

/*
形参:c_fd  --客户端套接字
      type  --文件类型
	  file  --要发送的文件
返回值:0成功,其它失败
*/
int Http_SendData(int c_fd,const char *type,const char *file)
{
	int fd=open(file,O_RDONLY);//打开文件
	if(fd<0)return -1;//打开文件失败
	struct stat statbuf;
	fstat(fd,&statbuf);
	if(statbuf.st_size<=0)
	{
		close(fd);
		return -2;
	}
	char buff[1024]={0};
	snprintf(buff,sizeof(buff),"HTTP/1.1 200 OK\r\n"
								"Content-type:%s\r\n"
								"Content-Length:%ld\r\n"
								"\r\n",type,statbuf.st_size);
	if(write(c_fd,buff,strlen(buff))!=strlen(buff))
	{
		close(fd);
		return -3;//发送数据头失败
	}
	/*发送文件内容*/
	int size;
	while(1)
	{
		size=read(fd,buff,sizeof(buff));
		if(write(c_fd,buff,size)!=size)break;//发送失败
		if(size!=sizeof(buff))break;//发送完成
	}
	close(fd);
	return 0;
}

int Http_SendPic(int c_fd,const char *type,const char *file)
{
	char buff[1024]={0};
	snprintf(buff,sizeof(buff),"HTTP/1.1 200 OK\r\n"
								"Content-type:%s\r\n"
								"Content-Length:%ld\r\n"
								"\r\n",type,614400);
	if(write(c_fd,buff,strlen(buff))!=strlen(buff))
	{
		return -3;//发送数据头失败
	}
	/*发送文件内容*/
	int size;
	int cnt = 0 ; 
	pthread_mutex_lock(&mutex);
	void *ppptr = jpg_buff;
	while(1)
	{
		int size= 1024;
		int wt_len = write(c_fd,ppptr,size);//发送失败
		cnt += wt_len ; 
		ppptr += wt_len ; 
		if(cnt >= 614400  ) {break;}//发送完成
	}
	pthread_mutex_unlock(&mutex);
	return 0;
}

int Http_SendPic1(int c_fd,const char *type,const char *file)
{
	char buff[1024]={0};
	snprintf(buff,sizeof(buff),"HTTP/1.1 200 OK\r\n"
			           "Server:LiMeng \r\n"
								"Content-type:image/jpeg\r\n"
								"Content-Length:%ld\r\n"
								"\r\n",614400);
	if(write(c_fd,buff,strlen(buff))!=strlen(buff))
	{
		return -3;//发送数据头失败
	}
	/*发送文件内容*/
	int size;
	int cnt = 0 ; 
	pthread_mutex_lock(&mutex);
	void *ppptr = jpg_buff;
	while(1)
	{
		int size= 1024;
		int wt_len = write(c_fd,ppptr,size);//发送失败
		cnt += wt_len ; 
		ppptr += wt_len ; 
		if(cnt >= 614400  ) {break;}//发送完成
	}
	pthread_mutex_unlock(&mutex);
	return 0;
}

/*
HTTP长连接处理客户端请求
"HTTP/1.0 200 OK\r\n"
"Server: wbyq\r\n"
"Content-Type:multipart/x-mixed-replace;boundary=boundarydonotcross\r\n"
"\r\n"
"--boundarydonotcross\r\n"
*/

int Http_Content(int c_fd)
{
	char buff[1024]={0};
	/*建立长连接*/
	snprintf(buff,sizeof(buff),"HTTP/1.0 200 OK\r\n"
				    "Server: wbyq\r\n"
				    "Content-Type:multipart/x-mixed-replace;boundary=boundarydonotcross\r\n"
				    "\r\n"
				    "--boundarydonotcross\r\n");
	if(write(c_fd,buff,strlen(buff))!=strlen(buff))return -1;//发送报文头失败
	int jpe_image_size = 614400;//保存jpeg图像大小
        //int send_html_cnt = 0 ;
	clock_t t1;
        t1 = clock();
        char save_name[10];
        int save_idx = 0 ;
        struct timeval start_time, end_time;
	while(1)
	{
	        //auto beg = clock();
                t1 = clock();
		pthread_cond_wait(&hasNode,&lock);
	        //printf("wait time is %d us \n",  (clock() - t1)   ); 
	        auto beg = clock();
	        gettimeofday(&start_time, NULL);
		/*
			(1)响应报文头
			"Content-type:image/jpeg\r\n"
			"Content-Length:666\r\n"
			"\r\n"
		*/
		snprintf(buff,sizeof(buff),	"Content-type:image/jpeg\r\n"
									"Content-Length:%d\r\n"
									"\r\n",jpe_image_size);
		if(write(c_fd,buff,strlen(buff))!=strlen(buff))
		{
			return -2;//响应报文头失败
		}
		/*发送jpg图像数据*/
		//pthread_mutex_lock(&mutex);//互斥锁上锁
                //pthread_cond_wait(&hasNode,&lock);
	        void *ppptr = jpg_buff;
	        //void *ppptr = ppp_tr;
                //sprintf(save_name,"my_%d.jpg",save_idx++);
	        //FILE *file=fopen(save_name, "w");
                //fwrite(ppptr , 614400, 1,file);
                //close(file);
		int cnt = 0 ; 
	        while(1)
         	{
		int size= 1024 * 600;
		//int size= 1024 ;
		int wt_len = write(c_fd,ppptr,size);//发送失败
		cnt += wt_len ; 
		ppptr += wt_len ; 
		if(cnt >= 614400  ) {break;}//发送完成
        	}  
		//pthread_mutex_unlock(&mutex);//互斥锁上锁
                //pthread_mutex_unlock(&lock);
	        //sleep(20);
		/*
			(3)发送间隔字符串
			"\r\n"
			"--boundarydonotcross\r\n"
		*/
		strcpy(buff,"\r\n--boundarydonotcross\r\n");
		if(write(c_fd,buff,strlen(buff))!=strlen(buff))
		{
			break;//发送间隔符失败
		}
	        auto end = clock();
	        gettimeofday(&end_time, NULL);
	        double timeuse = (end_time.tv_sec - start_time.tv_sec) + (double)(end_time.tv_usec - start_time.tv_usec) / 1000000.0;
	        //printf("sendtime is %d us \n",  (end - beg)   ); 
	        //printf("send cnt is %d us \n",  send_html_cnt   ); 
	        send_html_cnt++;
                //pthread_mutex_unlock(&lock);
		//usleep(40000);
	        //auto beg = clock();
	        //printf("sendtime is %d ms \n",  (end - beg)   ); 
	        printf("sendtime is %d ms \n",  timeuse   ); 
                pthread_mutex_unlock(&lock);
                usleep(1);
	}
	return -4;//发送图像数据失败
}

/*线程工作函数*/
void *pth_work(void *arg)
{
	int c_fd=*(int *)arg;
	free(arg);
	char buff[1024]={0};
	int size;
	size=read(c_fd,buff,sizeof(buff)-1);
	if(size<=0)
	{
		close(c_fd);
		pthread_exit(NULL);
	}
	buff[size]='\0';
	printf("buff=%s\n",buff);
	if(strstr(buff,"GET / HTTP/1.1"))//请求网页文件
	{
		Http_SendData(c_fd,"text/html","./html/image.html");
	}
	else if(strstr(buff,"GET /1.bmp HTTP/1.1"))
	{
		Http_SendData(c_fd,"application/x-bmp","./html/1.bmp");
	}
	else if(strstr(buff,"GET /my.jpg HTTP/1.1"))
	{
		//Http_SendData(c_fd,"application/x-jpg","./html/my.jpg");
		//Http_SendPic(c_fd,"application/x-jpg","./html/my.jpg");
		Http_Content(c_fd);
	}
	else if(strstr(buff,"GET /my_32.jpg HTTP/1.1"))
	{
		Http_SendData(c_fd,"application/x-bmp","./html/my_32.jpg");
	}
	else if(strstr(buff,"GET /100.bmp HTTP/1.1"))
	{
		Http_SendData(c_fd,"application/x-bmp","./html/100.bmp");
	}
	else if(strstr(buff,"GET /favicon.ico HTTP/1.1"))
	{
		Http_SendData(c_fd,"image/x-icon","./html/wmp.ico");
	}
	else
	{
		Http_SendData(c_fd,"application/x-jpg","./html/limeng.jpg");
		//Http_SendData(c_fd,"application/x-bmp","./html/my.jpg");
	}
	close(c_fd);
	//printf("22222222222222222222222   \n");
	pthread_exit(NULL);
}

int generate_pic() 
{
    int fd = open("/dev/video0",O_RDWR); //打开摄像头设备
    if (fd < 0)
    {
        perror("打开设备失败");
        return -1;
    }

    struct v4l2_format vfmt;

    vfmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //摄像头采集
    vfmt.fmt.pix.width = 640; //设置摄像头采集参数,不可以任意设置
    vfmt.fmt.pix.height = 480;
    vfmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG; //设置视频采集格式为mjpg格式
    
    int ret = ioctl(fd,VIDIOC_S_FMT,&vfmt);
    if (ret < 0)
    {
        perror("设置格式失败1");
    }

    //申请内核空间
    struct v4l2_requestbuffers reqbuffer;
    reqbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    reqbuffer.count = 4; //申请4个缓冲区
    reqbuffer.memory = V4L2_MEMORY_MMAP;  //映射方式

    ret = ioctl(fd,VIDIOC_REQBUFS,&reqbuffer);
    if (ret < 0)
    {
        perror("申请空间失败");
    }
   
    //映射
    unsigned char *mptr[4];//保存映射后用户空间的首地址
    unsigned int size[4];
    struct v4l2_buffer mapbuffer;
    //初始化type和index
    mapbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    for(int i = 0; i <4;i++) {
        mapbuffer.index = i;
        ret = ioctl(fd,VIDIOC_QUERYBUF,&mapbuffer); //从内核空间中查询一个空间作映射
        if (ret < 0)
        {
            perror("查询内核空间失败");
        }
        //映射到用户空间
        mptr[i] = (unsigned char *)mmap(NULL,mapbuffer.length,PROT_READ|PROT_WRITE,MAP_SHARED,fd,mapbuffer.m.offset);
        size[i] = mapbuffer.length; //保存映射长度用于后期释放
        //查询后通知内核已经放回
        ret = ioctl(fd,VIDIOC_QBUF,&mapbuffer); 
        if (ret < 0)
        {
            perror("放回失败");
        }
    }
    //开始采集
    int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret = ioctl(fd,VIDIOC_STREAMON,&type); 
    if (ret < 0){ perror("开启失败");}

    //定义一个空间存储解码后的rgb
    int sum = 0;//这里是用来控制读取的帧的数量 实际场景下 可以不要这个限制
    int read_cnt = 0 ;//记录读取图像线程
    char save_name[10];
    int save_idx = 0 ;
    struct timeval start_time, end_time;
    while(1)
    {
        struct v4l2_buffer readbuffer;
        readbuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; //每个结构体都需要设置type为这个参赛要记住
        ret = ioctl(fd,VIDIOC_DQBUF,&readbuffer); 
    	int read_len = mapbuffer.length;
    	int send_len = 1024;
    	//printf("%d \n",read_len);
        if (ret < 0)
         {
         perror("读取数据失败");
         }
	if(1)
	{
        //void *ptr = mptr[readbuffer.index];
	//pthread_mutex_lock(&mutex);
	//gettimeofday(&start_time, NULL);
        pthread_mutex_lock(&lock);
        void *ptr = mptr[readbuffer.index];
        ///ppp_tr = mptr[readbuffer.index];
	//auto beg = clock();
	//printf("read frame %d \n",beg);
	//printf("read frame %d  %d  %d \n",read_cnt++,send_html_cnt,beg);
	//pthread_mutex_lock(&mutex);
	memcpy(jpg_buff, ptr, readbuffer.length);//将读取到的图像拷贝到字符数组
	//ppp_tr = ptr ; 
	//auto end  = clock();
	//gettimeofday(&end_time, NULL);
	//double timeuse = (end_time.tv_sec - start_time.tv_sec) + (double)(end_time.tv_usec - start_time.tv_usec) / 1000000.0;
        sprintf(save_name,"my_%d.jpg",save_idx++);
	//int fd = open(save_name,  O_CREAT |O_WRONLY|O_TRUNC,0666);
	//char buf[1024*600]={0};
	//FILE *file=fopen(save_name, "w");
        //fwrite(mptr[readbuffer.index] , readbuffer.length, 1,file);
        //fwrite(ptr , readbuffer.length, 1,file);
        //close(file);
	//write(fd,buf,1024 * 600);
	//close(fd);
	pthread_mutex_unlock(&lock);
        pthread_cond_signal(&hasNode);
	//gettimeofday(&end_time, NULL);
	//pthread_mutex_unlock(&mutex);
	auto end  = clock();
	//printf("runtime is %f \n",  (end - beg) / CLOCKS_PER_SEC  ); 
	//printf("runtime is %f \n",  (end - beg)   ); 
	printf("runtime is %d ms \n",  timeuse   ); 
	//sleep(20);
	usleep(1);
	}

        //通知内核使用完毕
        ret = ioctl(fd, VIDIOC_QBUF, &readbuffer);
        if(ret < 0)
            {
                perror("放回队列失败");
            }
        }
        //停止采集
        ret = ioctl(fd,VIDIOC_STREAMOFF,&type);

        //释放映射
        for(int i=0; i<4; i)munmap(mptr[i], size[i]);

        close(fd); //关闭文件
        return 0;

    err1:
       close(fd_fb);
       return -1;
}

void shuijiao()
{
    struct timeval start_time, end_time;
    while(1){
	gettimeofday(&start_time, NULL);
	pthread_cond_wait(&hasNode,&lock);
	usleep(10000);
        pthread_mutex_unlock(&lock);
	gettimeofday(&end_time, NULL);
	double timeuse = (end_time.tv_sec - start_time.tv_sec) + (double)(end_time.tv_usec - start_time.tv_usec) / 1000000.0;
	//printf("shuijiao   time is %f  ms \n",  timeuse * 1000   );
	 }
}

int main()
{
	 int sockfd=socket(AF_INET,SOCK_STREAM,0);
	 if(sockfd==-1)
	 {
		 printf("创建网络套接字失败\n");
		 return 0;
	 }
	/*允许绑定已使用的端口号*/
	int on = 1;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	/*绑定端口号*/
	struct sockaddr_in s_addr=
	{
		.sin_family=AF_INET,//IPV4
		.sin_port=htons(HTTP_PORT),
		.sin_addr.s_addr=INADDR_ANY
	};
	if(bind(sockfd,(const struct sockaddr *)&s_addr,sizeof(s_addr)))
	{
		printf("绑定端口号失败\n");
		return 0;
	}
	/*设置监听数量*/
	listen(sockfd,100);
	/*等待客户端连接*/
	struct sockaddr_in c_addr;
	socklen_t len=sizeof(c_addr);
	int c_fd;
	pthread_t pthid;
	int *p=NULL;
	pthread_t pthid1;
	pthread_create(&pthid1,NULL,generate_pic,NULL);
	pthread_detach(pthid1);//设置为分离属性
	//shuijiao();
	//while(1){shuijiao();}
	while(1)
	{
		c_fd=accept(sockfd,(struct sockaddr *)&c_addr,&len);
		if(c_fd==-1)
		{
			printf("客户端连接失败\n");
			continue;
		}
		printf("套接字 : %d  连接成功,%s:%d\n",c_fd,inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port));
		p=malloc(4);
		*p=c_fd;
		pthread_create(&pthid,NULL,pth_work,p);
		pthread_detach(pthid);//设置为分离属性
	}
}

代码的编译命令是

gcc serv.c -o serv -ljpeg 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RSA--维纳攻击--代码和题目分析

文章目录 维纳攻击原理&#xff1a;维纳攻击脚本[羊城杯 2020]RRRRRRRSA 1题目描述&#xff1a;题目分析&#xff1a; 收获与体会&#xff1a; 维纳攻击原理&#xff1a; 两位大佬讲得非常清楚&#xff08;搬运工就是我&#xff09;&#xff1a;https://zhuanlan.zhihu.com/p/…

MyBatisPlus学习笔记(SpringBoot版)

MyBatisPlus学习笔记&#xff08;SpringBoot版&#xff09; 一、MyBatis-Plus简介1、简介2、特性3、支持数据库4、框架结构5、代码及文档地址 二、入门案例1、开发环境2、创建数据库及表2.1 创建表2.2 添加数据 3、创建Spring Boot工程3.1 初始化工程3.2 引入依赖3.3 idea中安装…

史上最烂 spring web 原理分析

盗引下篇spring web spring web、spring web 与 tomcat、映射器与适配器、参数解析器与类型转换器、返回值处理器与消息转换器、异常处理器、ControllerAdvice、spring web 工作流程。 版本 jdk&#xff1a;8spring&#xff1a;5.3.20spring boot&#xff1a;2.7.0 1 spring…

python调用海康sdk报错问题

sdk参考&#xff1a; (68条消息) Python调用海康威视网络相机_调用海康SDK_python 海康威视_有一点点麻瓜的博客-CSDN博客https://blog.csdn.net/yinweizhehd/article/details/118722052 报错1&#xff1a; 生成解决方案的时候&#xff0c;显示LNK2001&#xff1a;无法解析的…

如果你访问了某个网站,又不想让人知道怎么办?

问大家一个问题&#xff1a;如果你访问了某个网站&#xff0c;又不想让人知道怎么办&#xff1f; 你可能会说&#xff0c;把浏览器浏览历史记录清除&#xff0c;或者直接用无痕模式。 如果你只能想到这一层&#xff0c;那只能说图young&#xff01; 这么说吧&#xff0c;理论…

基于RK3588的8K智能摄像机方案设计

设计了一款基于石墨烯散热的8 K智能摄像头&#xff0c;主控采用瑞芯微RK3588&#xff0c;传感器采用索尼IMX435&#xff0c; 通过HDMI2.1将传感器采集到的图像发送到8 K显示器&#xff0c;实现端到端的8 K呈现&#xff0c;为了确保摄像头性能稳定&#xff0c;本 设计采用石墨烯…

计算机网络安全--期末

计算机网络安全绪论 计算机网络实体是什么 计算机网络中的关键设备&#xff0c;包括各类计算机、网络和通讯设备、存储数据的媒体、传输路线…等 典型的安全威胁有哪些 ★ ⋆ \bigstar\star ★⋆ 窃听(敏感信息被窃听)重传(被获取在传过来)伪造(伪造信息发送&#xff09;篡…

《花雕学AI》30:ChatGPT的资料来源比例排名前20名是什么?

引言&#xff1a;ChatGPT是一款由OpenAI开发的人工智能聊天机器人&#xff0c;它可以回答各种问题&#xff0c;并生成创意内容&#xff0c;如诗歌、故事、代码等。 ChatGPT的核心技术是基于GPT-3.5和GPT-4的大型语言模型&#xff0c;它可以利用从网路上收集的大量文本资料来进行…

MySQL执行顺序

MySQL执行顺序 MySQL语句的执行顺序也是在面试过程中经常问到的问题&#xff0c;并且熟悉执行顺序也有助于SQL语句的编写。 SELECT FROM JOIN ON WHERE GROUP BY HAVING ORDER BY LIMIT执行顺序如下&#xff1a; FROM ON JOIN WHERE GROUP BY # (开始使用别名) SUM # SUM等…

备战2个月,四轮面试拿下字节offer...

背景 菜 J 一枚&#xff0c;本硕都是计算机&#xff08;普通二本&#xff09;&#xff0c;2021 届应届硕士&#xff0c;软件测试方向。个人也比较喜欢看书&#xff0c;技术书之类的都有看&#xff0c;最后下面也会推荐一些经典书籍。 先说一下春招结果&#xff1a;拿下了四个…

vmware 安装Kylin-Desktop-V10-SP1-General-Release-2203-X86_64.iso

下载 官网&#xff1a;国产操作系统、银河麒麟、中标麒麟、开放麒麟、星光麒麟——麒麟软件官方网站 (kylinos.cn) 点击桌面操作系统 选择No1 点击申请试用 填写相关信息&#xff0c;点击立即提交&#xff0c;就会获取到下载连接&#xff0c; 点击下载按钮等待下载完成即可 安…

Go有序map:orderedmap

有序映射 与传统的无序映射&#xff08;Map&#xff09;不同&#xff0c;orderedmap包中的有序映射&#xff08;OrderedMap&#xff09;可以记录键值对的插入顺序。orderedmap提供了一些有用的API&#xff0c;用来存储、删除、查询和遍历键值对。 获取OrderedMap 你可以通过Ord…

编译安装最新的Linux系统内核

现在还有不少机器是CentOS8 Stream系统&#xff0c;虽然上了贼船&#xff0c;不影响用就是了。8的编译和7大同小异&#xff0c;只是踩了更多的坑在这里记录一下&#xff0c;或许会帮到看到的朋友。 安装编译环境 CentOS8安装必要的包 yum groupinstall "Development Too…

2022年NOC大赛编程马拉松赛道复赛图形化高年级A卷-正式卷,包含答案

目录 单选题: 多选题: 编程题: 下载打印文档做题: 2022年NOC大赛编程马拉松赛道复赛图形化高年级A卷-正式卷,包含答案 单选题:<

《Netty》从零开始学netty源码(五十三)之PoolThreadCache的功能

allocateNormal 在前面分析PoolArena的分配内存的方法中&#xff0c;每次分配都是先从本地线程缓存中分配&#xff0c;本地线程缓存PoolThreadCache的分配方法如下&#xff1a; 分配过程主要有两步&#xff1a; 从PoolThreadCache的缓存数组中获取相应大小的缓存cache将需要…

桌面虚拟化的优势

启用基于云的虚拟桌面基础架构 &#xff08;VDI&#xff09; OpenText™ Exceed TurboX™ &#xff08;ETX&#xff09; 长期以来一直是虚拟化在 Linux 主机上运行的图形要求苛刻的软件的黄金标准。ETX 最新版本&#xff08;12.5&#xff09;增加了许多Microsoft Windows功能&…

智能座舱的“宏大蓝图”和“残酷现实”

配图来自Canva可画 2023年上海车展各大车企发布新车、新配置和新战略好不热闹&#xff0c;“智能驾驶”、“智能座舱”等关键词频频出现&#xff0c;智能化已然成为车企技术比拼的关键。 Unity中国发布最新智能座舱解决方案&#xff0c;可为车企提供成熟、可量产落地的HMI&…

什么是点对点传输?什么是点对多传输

点对点技术&#xff08;peer-to-peer&#xff0c; 简称P2P&#xff09;又称对等互联网络技术&#xff0c;是一种网络新技术&#xff0c;依赖网络中参与者的计算能力和带宽&#xff0c;而不是把依赖都聚集在较少的几台服务器上。P2P网络通常用于通过Ad Hoc连接来连接节点。这类网…

深度学习 - 46.DIN 深度兴趣网络

目录 一.引言 二.摘要 ABSTRACT 三.介绍 INTRODUCTION 1.CTR 在广告系统的作用 2.传统 MLP 存在的问题 3.DIN 的改进 四.近期工作 RELATEDWORK 1.传统推荐算法 2.用户行为抽取 五.背景 BACKGROUD 六.深度兴趣网络 DEEP INTEREST NETWORK 1.特征表示 Feature Repres…

triton 疑难手册

config.pbtxt 配置参数手册 backend或platform参数用于指示nvidia triton用对应的backend加载模型参数,它的使用示例如下: name: "xxx" platform: "pytorch_libtorch"max_batch_size: 8 input [ {name: "input0"data_type: TYPE_UINT8dims: …