当前位置: 首页 > news >正文

网络编程 tcp udp http编程流程 网络基础知识

讲解

  • 网络基础知识
  • 网络编程
    • tcp编程流程
      • 图示理解
      • bind和accept函数理解
      • 监视套接字和链接套接字理解
      • linux和window下的编程实现
      • tcp特点
    • udp编程流程
      • 图示理解
      • udp特点
    • http编程流程
      • 图示+理解
      • 编程实现-网站服务器

网络基础知识

OSI分层:应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
tcp/ip: 应用层 传输层 网络层 数据链路
ip地址:唯一标识一台主机
ipv4 32位 ipv6 128位 寻址 可以反映物理上的一个变化
MAC地址:48 固化在计算机中
ip地址又两部分构成:网络号+主机号
端口号:标识一个应用程序的代号 短整型
协议:共同遵守的约定 tcp协议 网络中的规则
ip , http/https,/ftp, tcp/
ipv4头部结构
在这里插入图片描述
4位头部长度:表示15行 每行4字节就是60字节 减去 基本的20字节 剩余的选项 40字节
TCP头部结构
在这里插入图片描述

剩余的选项仍然是 40字节
应用程序传递数据的一个过程
tcp协议

在这里插入图片描述
这四层:应用层 传输层 网络层 数据链路

在这里插入图片描述
ip地址由网络号和主机号共同构成的

"129.168.1.1"点分十进制转化为
无符号整型:
unsignal int inet_addr();
无符号整型转化为点分十进制:
inet_ntoa();
在这里插入图片描述
每一个字节8位 都是十进制转化的,最后将四个字节组合在一起,变成一个无符号整型

大端:网络字节序列 htons()
地址:ip+port

表示Ipv4的地址结构

struct socketaddr_in ipv4;

通用的套接字地址

struct socketaddr;

套接字
像手机一样进行数据的收发

需要让服务器先运行起来,客户端主动连接服务器,所以服务器需要把自己的ip 和端口告诉客户端

在Windows下查看ip地址

ipconfig

在这里插入图片描述

Linux下查看虚拟机ip地址

ifconfig

在这里插入图片描述
判断两个主机是否连通

ping 

在这里插入图片描述
无法访问目标主机 ,说明该网络下没有这个主机
请求超时,可能有防火墙 没有成功

网络编程

tcp编程流程

图示理解

tcp服务器 ,客户端编程流程
在这里插入图片描述

bind和accept函数理解

bind就是看看saddr得ip地址端口有没有问题,ip地址是不是写错了,端口是不是被占用了,如果没有问题,就将表示符合该地址绑定,取名成功

int c = accept(sockfd, (struct sockaddr *)&caddr, &len);

服务器会在该行阻塞,等待用户端的连接,一旦connect成功,阻塞结束,得到新的描述符c,该c对应刚才的客户端,类似一个链接,每个c都对应一个客户端,表示一条链接。

监视套接字和链接套接字理解

监听套接字 都是这一个 类似文件描述符 在一个进程中,fd都是3 不变
链接套接字:一个链接 由于服务器012 被占用 监视套接字是3 所以链接套接字从4开始,说明一个客户端和服务器链接上了,如果另一个客户端链接,那就是5 …
如果不理解,可以看这篇文章,讲的挺通俗易懂的:
监视套接字和链接套接字

int c = accept(sockfd,(struct sockaddr*) &caddr,&len);//阻塞
服务器刚开始是不知道客户端的地址的,所以先 &caddr 把结构体放这里,等客户端根据服务器给的ip端口找到connect,此时accept接收,这个时候就知道了客户端的地址和ip,存储在caddr

为什么c变成了4 原来的sockfd是3 而客户端的sockfd一直是3
类似用你的手机3给10086电话,你的电话号不变,一直是3 服务器类似一个服务中心,服务器刚开始也是10086 即3号手机接收,接听到了一个用户,就转接到另一个人工客服接听,即4 号手机,原来的3号手机继续接听客户的电话。一次类推。

linux和window下的编程实现

ser.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>int main()
{int sockfd = socket (AF_INET,SOCK_STREAM,0);if(sockfd == -1){exit(1);}struct sockaddr_in saddr, caddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.s_addr = inet_addr("192.168.1.49");//“127.0.0.1”int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if ( res == -1){printf("bind err\n");exit(1);}res = listen(sockfd,5);if ( res == -1 ){exit(1);}while( 1 ){socklen_t len = sizeof(caddr);int c = accept(sockfd,(struct sockaddr*) &caddr,&len);//阻塞if ( c < 0 ){continue;}printf("accept c=%d\n",c);char buff[128] = {0};int n = recv(c,buff,127,0);//阻塞printf("buff=%s\n",buff);send(c,"ok",2,0);close(c);}
}

cli.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>int main()
{int sockfd = socket(AF_INET,SOCK_STREAM,0);if ( sockfd == -1){exit(1);}struct sockaddr_in saddr;memset(&saddr,0,sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.s_addr = inet_addr("192.168.1.49");int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if ( res == -1){printf("connect err\n");exit(1);}send(sockfd,"hello",5,0);char buff[128] = {0};recv(sockfd,buff,127,0);//okprintf("buff=%s\n",buff);close(sockfd);
}

Windows系统上的服务器和客户端

//window servier
#if 0
//ConsoleApptcp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <WinSock2.h>   //网络头文件
#include <string.h>
#include <ws2tcpip.h>  //socklen_t
#include <iostream>using namespace std;
#pragma comment(lib, "ws2_32.lib")   //网络库文件//初始化网络库
void InitNetwork() {WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD(2, 2);err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){return;}}int main()
{InitNetwork();SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == INVALID_SOCKET){cout << "socket err" << endl;return 0;}struct sockaddr_in saddr;memset(&saddr, 0, sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);//saddr.sin_addr.S_un.S_addr = INADDR_ANY;saddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.32");//这个要用需要加宏定义//saddr.sin_addr.S_un.S_addr = inet_pton(AF_INET,"192.168.1.50",NULL);int res = bind(sockfd, (SOCKADDR*)&saddr, sizeof(saddr));if (res == SOCKET_ERROR){cout << "bind err" << endl;return 0;}if (listen(sockfd, 5) == SOCKET_ERROR){cout << "listen err" << endl;return 0;}while (true){//struct sockaddr_in caddr;SOCKADDR_IN caddr;socklen_t len = sizeof(caddr);int c = accept(sockfd, (SOCKADDR*)&caddr, &len);if (c == INVALID_SOCKET){continue;}cout << "accept c=" << c << endl;char buff[128] = { 0 };while (true){if (recv(c, buff, 127, 0) <= 0){break;}cout << buff << endl;send(c, "ok", 2, 0);}closesocket(c);}}
#endif//windows client 
#if 0
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <WinSock2.h>   //网络头文件
#include <string.h>
#include <ws2tcpip.h>  //socklen_t
#include <iostream>using namespace std;
#pragma comment(lib, "ws2_32.lib")   //网络库文件//初始化网络库
void InitNetwork() {WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD(2, 2);err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){return;}}int main()
{InitNetwork();SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == INVALID_SOCKET){cout << "socket err" << endl;return 0;}struct sockaddr_in saddr;memset(&saddr, 0, sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(6000);saddr.sin_addr.S_un.S_addr = inet_addr("192.168.1.49");int res = connect(sockfd, (struct sockaddr*)&saddr, sizeof(saddr));if (res == -1){cout << "connect err" << endl;closesocket(sockfd);WSACleanup();}while (true){cout << "input" << endl;char buff[128] = { 0 };cin >> buff;if (strncmp(buff, "end", 3) == 0){break;}send(sockfd, buff, strlen(buff), 0);memset(buff, 0, 128);recv(sockfd, buff, 127, 0);cout << buff << endl;}closesocket(sockfd);WSACleanup();return 0;
}
#endif

tcp特点

 int n = recv(c,buff,1,0);

一次只收一个字符
在这里插入图片描述

当发送速度快,会一起写到缓冲区,然后一起发送,数据太大,会拆开发送
在这里插入图片描述
套接字有发送缓冲区和接收缓冲区

netstat


应答确认 超时重传
乱序重拍 去重
滑动窗口控制
tcp特点
面向连接的 可靠的 流式服务

udp编程流程

图示理解

在这里插入图片描述

udp特点

无连接 不可靠 数据报服务
双方无连接:服务器关了,再起启动,发送消息还是能收到,在建立一个客户端,也可以发送信息。
udp发送数据时,要保证数据收完,否则其他数据就丢了
严格的一对一,发几次收几次

一个端口可以被一个套接字绑定,可以绑定两个,是协议不同
在这里插入图片描述
tcp在应用层面不丢数据,底层会丢,网络层,丢了重发就行,tcp自身保证其可靠性
tcp适合传文件 丢一个字节都不行
udp适合视频通话 丢包就是卡了

http编程流程

图示+理解

在这里插入图片描述

应用层 http 浏览器和服务器之间的通讯
传输层 tcp

两次以上的请求复用了同一个tcp连接,就是长连接
http用80号端口
https用443号端口
小于1024的端口,需要管理员才能访问
在这里插入图片描述
后面有\r\n结束

在这里插入图片描述
在这里插入图片描述
最后一行还有一个\r\n
content_length 不包含报头
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
服务器收到浏览器的信息,放到buff数组里,服务器知道了浏览器想访问的资源就是index.html,服务器需要做的是找到该资源,发给浏览器就行

在这里插入图片描述
浏览器会自己发起一个请求,去访问图标
这是一组请求,可能会有多次请求,在一次点击的过程中
在这里插入图片描述

编程实现-网站服务器

myhttp.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include<fcntl.h>
#define PATH "/home/ittao/code/day17"
int socket_init();
char *get_filename(char buff[])
{if(buff==NULL){return NULL;}char *ptr=NULL;char*s=strtok_r(buff," ",&ptr);if(s==NULL){return NULL;}printf("way:%s\n",s);s=strtok_r(NULL," ",&ptr);return s;
}
void *thread_fun(void *arg)
{int c = (int)arg;while (1){char buff[4096] = {0};int n = recv(c, buff, 4095, 0);if(n<=0){break;}printf("buff:%s\n", buff);char*filename=get_filename(buff);if(filename==NULL){send(c,"http err:404",12,0);break;}printf("filename:%s\n",filename);char path[256]={PATH};if(strcmp("/",filename)==0){strcat(path,"/index.html");}else{strcat(path,filename);}int fd=open(path,O_RDONLY);if(fd==-1){send(c, "http err:404", 12, 0);}int filesize=lseek(fd,0,SEEK_END);lseek(fd,0,SEEK_SET);char http_head[256]={" my HTTP/1.1 200 OK\r\n"};strcat(http_head,"Server:myhttp\r\n");sprintf(http_head+strlen(http_head),"Content-Length:%d\r\n",filesize);strcat(http_head,"\r\n");send(c,http_head,strlen(http_head),0);char data[1024];int num=0;while((num=read(fd,data,1024))>0){send(c,data,num,0);}close(fd);}close(c);printf("client close\n");pthread_exit(NULL);
}
int accept_client(int sockfd)
{struct sockaddr_in caddr;int len = sizeof(caddr);int c = accept(sockfd, (struct sockaddr *)&caddr, &len);return c;
}
int main()
{int sockfd = socket_init();if (sockfd == -1){exit(1);}while (1){int c=accept_client(sockfd);if (c != -1){pthread_t id;pthread_create(&id, NULL, thread_fun, (void *)c);} }
}
int socket_init()
{int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd == -1){return -1;}struct sockaddr_in saddr;memset(&saddr, 0, sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(80);saddr.sin_addr.s_addr = inet_addr("192.168.1.49");int res = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));if (res == -1){printf("bind err\n");return -1;}res = listen(sockfd, 5);if (res == -1){return -1;}return sockfd;
}

相关文章:

网络编程 tcp udp http编程流程 网络基础知识

讲解 网络基础知识网络编程tcp编程流程图示理解bind和accept函数理解监视套接字和链接套接字理解linux和window下的编程实现tcp特点 udp编程流程图示理解udp特点 http编程流程图示理解编程实现-网站服务器 网络基础知识 OSI分层&#xff1a;应用层 表示层 会话层 传输层 网络层…...

LaTeX基础学习笔记

LaTeX是一个文本编辑器。其类似于markdown&#xff0c;使用特殊标记和代码来修改文本格式&#xff0c;创建特殊字符等。可以使用overleaf在线LaTex编辑器编写LaTeX并转换为pdf文件&#xff08;https://www.overleaf.com/&#xff09; 同时推荐一个网站http://detexify.kirelab…...

zookeeper和kafka

目录 一、zookeeper理论 1.1、zookeeper定义 1.2、zookeeper工作机制 1.3、zookeeper特点 1.4、zookeeper的数据结构 1.5、zookeeper应用场景 1.6、zookeeper的选举机制 二、部署Zookeeper 集群 2.1、环境准备 2.2、安装 Zookeeper 2.3、修改配置文件 2.4、配置…...

服务器无法加载海康sdk依赖的问题

首先遇到的jna.jar和examples.jar无法加载的问题&#xff0c;尝试了很多方法无效&#xff0c;以下方法实测有效 其次是动态链接库无法加载的问题&#xff0c;而且是播放库&#xff0c;我的方法比较简单&#xff0c;netsdk加载出来就行了&#xff0c;播放库用不到&#xff0c;删…...

brew+nginx配置静态文件服务器

背景 一下子闲下来了&#xff0c;了解的我的人都知道我闲不下来。于是&#xff0c;我在思考COS之后&#xff0c;决定自己整一个本地的OSS&#xff0c;实现静态文件的访问。那么&#xff0c;首屈一指的就是我很熟的nginx。也算是个小复习吧&#xff0c;复习一下nginx代理静态文…...

JavaFx异常: Not on FX application thread; currentThread = Timer-0

我的定时器任务中有两个控件&#xff1a; FXML TextArea Display; FXML Label Label_Display; 执行下方代码会抛出&#xff1a;Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread Timer-0 Timer_tas…...

【Django】无法从“django.utils.encoding”导入名称“force_text”

整晚处理 Django 的导入错误。 我将把它作为提醒&#xff0c;希望处于相同情况的人数会减少。 原因 某些软件包版本不支持Django 4 请看下表并决定Django和Python的版本 方案 如果出现难以响应&#xff0c;或者更改环境麻烦&#xff0c;请尝试以下操作 例如出现以下错误 …...

docker-compose redis 一直启动失败

环境&#xff1a; centos 8.x 背景 使用docker-compose 来启动redis docker-compose.yml 如下&#xff1a; version: 3.3 services:redis:image: redis:latestrestart: alwayscontainer_name: redisports:- 6379:6379volumes:- ./data:/redis/data- ./redis.conf:/redis/re…...

使用GUI Guider工具在MCU上开发嵌入式GUI应用 (1) - GUI Guider简介及安装

使用GUI Guider工具在MCU上开发嵌入式GUI应用 (1) - GUI Guider简介及安装 受限于每篇文章最多只能贴9张图的限制&#xff0c;这个教程被拆分成了多篇文章连载发布&#xff0c;完整目录结构如下图x所示。后续会发布完整教程的pdf文件&#xff0c;敬请期待。 图x 完整教程文档…...

解决:django设置DEBUG=false时出现的问题

首先&#xff0c;我用的是django4.2&#xff0c;python3.10版本 本来&#xff0c;如果在settings.py中使用 DEBUG True&#xff0c;那么什么问题也没有&#xff0c;当然&#xff0c;这属于调试模式。 DEBUG True TEMPLATE_DEBUG DEBUGSTATIC_URL /static/ STATICFILES_DI…...

2023-08-10力扣每日一题

链接&#xff1a; 1289. 下降路径最小和 II 题意&#xff1a; 每一行选择一个数字&#xff0c;相邻行选择不能是同一列&#xff0c;求选择的数字和最小是多少 解&#xff1a; 每一行选择最小的次小的&#xff0c;下一行能加最小的&#xff08;列坐标不冲突&#xff09;就加…...

C#与halcon联合 缩放移动自适应图像

读取图片 //获取文件路径下的图片public HObject GetImgFromPath(string imgPath){HObject L_Img;HOperatorSet.GenEmptyObj(out L_Img);//清空图片L_Img.Dispose();//释放HOperatorSet.ReadImage(out L_Img, imgPath);//读取图片存入到l_imgreturn L_Img;}拉伸显示 //图片拉…...

推荐 4 个 yyds 的 GitHub 项目

本期推荐开源项目目录&#xff1a; 1. 开源的 Markdown 编辑器 2. MetaGPT 3. SuperAGI 4. 一个舒适的笔记平台 01 开源的 Markdown 编辑器 Cherry 是腾讯开源的 Markdown 编辑器&#xff0c;基于 Javascript具有轻量简洁、易于扩展等特点&#xff0c; 它可以运行在浏览器或服…...

chrome插件开发实例05-页面间通信

目录 一、页面间通信的方式 方式1: 通过消息通信...

linux安装ftp

一、安装 参考博客 https://blog.csdn.net/dafeigecsdn/article/details/126518069 rpm -qa |grep vsftpd # 查看是否安装ftp yum -y install vsftpd # 安装vsftpuseradd -d /home/lanren312 lanren312 # 指定在/home目录下创建用户 passwd lanren312 # 给用户设置密码 # 输…...

前后端分离------后端创建笔记(上)

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…...

Java不可变集合详解

什么是不可变集合 不可变集合&#xff0c;英文叫 immutable 顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供&#xff0c;并且在整个生命周期中都不可改变。 为什么要使用不可变集合 不可变对象有很多优点&#xff0c;包括&#xff1a; 当对象被不可信的…...

常见的JavaScript日常问题

在众多的编程语言中&#xff0c; JavaScript 给大部分的人的第一印象是人畜无害&#xff0c;看起来就简单的&#xff0c;对稍微有点儿开发经验的人来说&#xff0c;在网页中写个JavaScript功能也相当简单。但是当你真的得了解了JavaScript之后就会发现&#xff0c;它比我们想象…...

css modules的用法和在react项目中的应用

参考文章 CSS Modules 的用法 CSS Modules 的功能很单纯&#xff0c;只加入了局部作用域和模块依赖&#xff0c;可以保证某个组件的样式&#xff0c;不会影响到其他组件。 局部作用域 CSS的规则都是全局的&#xff0c;任何一个组件的样式规则&#xff0c;都对整个页面有效。…...

【LangChain概念】了解语言链️:第2部分

一、说明 在LangChain的帮助下创建LLM应用程序可以帮助我们轻松地链接所有内容。LangChain 是一个创新的框架&#xff0c;它正在彻底改变我们开发由语言模型驱动的应用程序的方式。通过结合先进的原则&#xff0c;LangChain正在重新定义通过传统API可以实现的极限。 在上一篇博…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M&#xff1a;百万&#xff08;Million&#xff09; B&#xff1a;十亿&#xff08;Billion&#xff09; 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的&#xff0c;但是一个参数所表示多少字节不一定&#xff0c;需要看这个参数以什么…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

相机从app启动流程

一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...