https下载图片
OpenSSL用法示例
OpenSSL源码安装
对于ubuntu,懒得编译源码可以直接安装
sudo apt-get install libssl–dev
/usr/include/openssl/ssl.h
CMakeLists中添加
link_libraries(ssl crypto)
apt-get安装不需要再制定libssl.a, libcrypto.a的路径了, 就像用libc标准库一样。源码安装要指定-L/path/to/libssl.a或者-L/path/to/libssl.so , -lssl。客户端不需要生成证书。
sale.txt
GET /uploadfile/photo/20231022/37cac8bc693780b740b4e659846689cd.jpg HTTP/1.1
Accept: image/jpeg,image/avif,image/webp,image/apng,*/*
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7,ja;q=0.6
Connection: keep-alive
Host: img.sx2737.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36
* main.c
#include <string.h>
/* ... */
#include "https.h"static int get_host_ip(char ip[], char hostname[]) {struct ipv4head ipv4List;struct ipv4_entry *n1;int count = 0;/* get ip by Gateway 10.0.0.1 */bcl_dns_query(&ipv4List, hostname, "10.0.0.1");while(!TAILQ_EMPTY(&ipv4List)) {n1 = TAILQ_FIRST(&ipv4List);TAILQ_REMOVE(&ipv4List, n1, entries);printf("ip=%s\n", n1->data);strncpy(ip, n1->data, 16);free(n1);count += 1;}return count;
}int main(int argc, char *argv[]) {char path_dst[256];char path_src[256];char hostname[32] = {'\0'};char ip[16] = {'\0'};int sockfd = -1;bclerrinit();strcpy(path_src, "/mnt/e/CLionProjects/arp/fap30/input/sale.txt");strcpy(path_dst, "/mnt/e/CLionProjects/arp/fap30/print/sale.jpg");strcpy(hostname, "img.sx2737.com"); /* octipus.net, www.google.co.il */get_host_ip(ip, hostname);printf("path_dst=%s\n", path_dst);if (E_FAIL == https_get_body(ip,path_src, path_dst)) {bclerrlog(E_SOCKFD_RECV, _FL_, "https_get_body(%s,%s,%s)",ip,path_src,path_dst);return E_FAIL;}bclerrend();return E_OK;
}
网关直接固定写的10.0.0.1, 需要改。或者再实现一个拿到网关Gateway IP地址的函数 查DNS
DNS没做缓存,简化版测试查询DNS发UDP包。 一个域名对应多个ip,也不知道多少个ip,用的/usr/include/x86_64-linux-gnu/sys/queue.h 参照下面的bcl_udp.h
#include <sys/queue.h>
* https.h
#ifndef ARP_TEST_HTTPS_H
#define ARP_TEST_HTTPS_H#include <openssl/ssl.h> /* SSL_Library_init() */
#include <openssl/err.h>int https_get_body(char *ip, char *in_path, char *out_path);#endif //ARP_TEST_HTTPS_H
* https.c
/** @ref: https://aticleworld.com/ssl-server-client-using-openssl-in-c/* sudo apt-get install libssl–dev* -L/path/to/ssl_dir -lssl -lcrypto*/
#include <string.h> /* memset */
/* ... */
#include "https.h"extern unsigned int ip2int(const char *ip);static SSL_CTX *InitCTX(void) {SSL_METHOD *method;SSL_CTX *ctx;OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */SSL_load_error_strings(); /* Bring in and register error messages */method = TLSv1_2_client_method(); /* Create new client-method instance */ctx = SSL_CTX_new(method); /* Create new context */if ( ctx == NULL ) {ERR_print_errors_fp(stderr);abort();}return ctx;
}ssize_t send_from_file_ssl(SSL *ssl, char *path) {byte_t *buf = NULL;size_t isz = 0;ssize_t outBytes;buf = file_get_contents(path, &isz);outBytes = SSL_write(ssl, buf, isz);/* bcl_xxd(buf, isz); */free(buf);return outBytes;
}int https_get_body(char *ip, char *in_path, char *out_path) {SSL_CTX *ctx = NULL;SSL *ssl;int bytes;
#define HTTPS_BUFF_SIZE 4096char buf[HTTPS_BUFF_SIZE];int sockfd = -1;FILE *out = NULL;SSL_library_init();ctx = InitCTX();ssl = SSL_new(ctx); /* create new SSL connection state */sockfd = bcl_tcp_connector(ip2int(ip), 443);SSL_set_fd(ssl, sockfd); /* attach the socket descriptor */if ( SSL_connect(ssl) < 0 ) { /* perform the connection */ERR_print_errors_fp(stderr);return E_FAIL;}send_from_file_ssl(ssl, in_path);bytes = SSL_read(ssl, buf, HTTPS_BUFF_SIZE);/* Dump HTTP header */bcl_xxd(buf, bytes);out = fopen(out_path, "w");if (NULL == out) {bclerreg(E_OSCALL, _FL_, "fopen(%s)", out_path);return E_FAIL;}while (0<(bytes = SSL_read(ssl, buf, HTTPS_BUFF_SIZE))) {fwrite(buf, 1, bytes, out);memset(buf, 0, bytes);}fclose(out);bcl_closesock(sockfd);SSL_free(ssl);SSL_CTX_free(ctx);return E_OK;
}
先准备ssl需要的库, SSL_Libary_init(), 创建SSL_CTX *ctx对象
封装socket fd为SSL *, 操作SSL *取代 int fd。SSL_read替换recv, SSL_write替换send
close(fd)关闭socket fd。用完SSL_free(ssl), 释放https链接。销毁SSL_CTX *ctx对象
SSL_read第0次调用拿到http header,再调用得到的是http body。不需要手动解析http \r\n 0x0d 0x0a, 也省了很多麻烦。
int bcl_tcp_connector(u_int32_t _addr, u_int16_t _port) {struct sockaddr_in saddr;int sock;int ret;for (;;) {sock = socket(AF_INET, SOCK_STREAM, 0);if (sock <0) {/* ... */return E_FAIL;}memset(&saddr, 0x00, sizeof (saddr));saddr.sin_family = AF_INET;saddr.sin_addr.s_addr = _addr;saddr.sin_port = htons(_port);ret = connect(sock, (struct sockaddr *)&saddr, sizeof(saddr));if (ret >= 0) {return sock;}/* ERROR connect */if (errno == EINTR) {bcl_closesock(sock);continue;}char ip[16];bcl_int2ip(ip, _addr);bclerreg(E_OSCALL, _FL_, "Error connect %s:%d", ip, _port);return E_FAIL;}
}
创建socket fd,调用connect,常规方法。
bcl_xxd函数hexdump调试用
uint8_t arc_xxd(byte *s, uint8_t len, void *param);void bcl_xxd(const void *s, size_t len)
{uint16_t line = 0;byte *t = (byte *)s;uint8_t b;size_t left = len;for (; ;) {if (left > 16) {b = arc_xxd(t, 16, &line);} else {b = arc_xxd(t, left, &line);}if (b < 1) {break;}left -= b;if (left <= 0) {break;}t += b;}
}uint8_t arc_xxd(byte *s, uint8_t len, void *param)
{uint8_t i;uint16_t *line = (uint16_t *)param;fprintf(stdout, "%08x:", *line << 4);for (i = 0; i+2 < len; i+=2) {fprintf(stdout, " %02x%02x", s[i], s[i+1]);}if (i <len) {fprintf(stdout, " %02x", s[i]); i+= 1;}if (i <len) {fprintf(stdout, "%02x", s[i]); i+=1;}if (i < 16 && 0x00 != (i & 0x01)) { fputs(" ", stdout); i+=1;}for (; i <16; i+= 2) {fputs(" ", stdout); /* space * 5 */}fputs(" ", stdout);for (i = 0; i <len; i++) {if (s[i] <0x20 || s[i] > 0x7e) {fputc('.', stdout);} else {fputc(s[i], stdout);}}fputs("\r\n", stdout);*line += 1;return i;
}
* bcl_udp.h
#ifndef ERRLOG_BCL_UDP_H
#define ERRLOG_BCL_UDP_H#include <sys/queue.h>typedef union {unsigned char c[4];unsigned int addr;
} IPv4_t;void IPv4_toString(char *s, IPv4_t ipv4);
/* in_addr_t */ unsigned int ip2int(const char *ip);struct ipv4_entry {char data[16];TAILQ_ENTRY(ipv4_entry) entries;
};
TAILQ_HEAD(ipv4head, ipv4_entry);int bcl_dns_query(struct ipv4head *head, char *host_name, const char *dns_ip);#endif //ERRLOG_BCL_UDP_H
* bcl_udp.c
#ifdef __cplusplus
extern "C" {
#endif#include <strings.h> /* bzero */
#include <arpa/inet.h> /* inet_addr */
#include <unistd.h> /* close */
#include <string.h> /* strcat, memset */
#include <stdlib.h> /* getenv(), rand() */#include "bcl_udp.h"
#include "arclog.h"
#include "bcl_socket.h"#define PRIVATE staticunsigned int /* in_addr_t */ip2int(const char *ip) {IPv4_t un;int i, j;un.c[0] = un.c[1] = un.c[2] = un.c[3] = 0;for (i = 0, j = 0; i < 16 && ip[i] != '\0'; i++) {if (0x30 <= ip[i] && ip[i] < 0x3a) { /* '0','9' */un.c[j] *= 10;un.c[j] += ip[i] - 0x30;} else if (ip[i] == 0x2e) { /* '.' */j += 1;}}return un.addr;
}typedef struct {u_short transId; /* 0xb6f6 */u_short flags; /* 0x0100 Standard query */u_short questions; /* 0x0001 */u_char rss[6]; /* 00 00 00 00 00 00 */
} DnsHdr_t;#define HOST_LEN 64typedef struct {u_char name[2]; /* ptr */u_short type; /* 0x0005 alias */u_short in; /* 0x0001 */u_int32_t ttl; /* 81, 1min21s */u_short dataLen; /* 0x0017, 23 */char cname[HOST_LEN]; /* 3www31633com8163jiasu3com */
} __attribute__((packed)) DnsAnswer_t;/*** @ref: https://www.linuxquestions.org/questions/linux-networking-3/dns-packet-structure-289886/* @param name "p3-sign.douyinpic.com"* @param entry "7p3-sign9douyinpic3com"* @return*/
PRIVATE char *dns_entry(char *entry, const char *name) {const char *p = name;char *q = entry;int8_t len;while ('\0' != *p) {len = 0;for (; *p && *p != '.'; p++) {len += 1;}*q++ = len;memcpy(q, p - len, len);q += len;p++;}return q;
}#define SWAP(a, b, type) do { type _t = a; a = b; b = _t;} while(0);#define REVERSE(a, b, type) do { \type *p = a, *q = b; \type t; \if (p > q) { SWAP(p, q, type *);} \for (; p < q; p++, q--) { \t = *p; \*p = *q; \*q = t; \} \
} while (0);void IPv4_toString(char *s, IPv4_t ipv4) {int i;char *t;
#ifdef __ORDER_LITTLE_ENDIAN__for (i = 0; i < 4; i++) {
#elsefor (i = 3; 0 <= i; i--) {
#endift = s;while (ipv4.c[i]) {*s++ = ipv4.c[i] % 10 + 0x30;ipv4.c[i] /= 10;}REVERSE(s-1, t, char);*s++ = '.';}*(s-1) = '\0';
}int bcl_dns_query(struct ipv4head *head, char *host_name, const char *dns_ip) {int sockfd;char buf[1024] = {'\0'};struct sockaddr_in dest_addr;DnsHdr_t header;char *p = NULL;off_t queryLen;DnsAnswer_t ans;IPv4_t ipv4;struct ipv4_entry *n1 = NULL;sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {bclerreg(E_OSCALL, _FL_, "socket() UDP");return E_FAIL;}/* DNS address */memset(&dest_addr, 0, sizeof(struct sockaddr_in));dest_addr.sin_family = AF_INET;dest_addr.sin_addr.s_addr = ip2int(dns_ip);dest_addr.sin_port = htons(53); /* DNS port 53 */if (connect(sockfd, (const struct sockaddr *) &dest_addr, sizeof(dest_addr)) < 0) {bclerreg(E_OSCALL, _FL_, "connect()");return E_FAIL;}/* DNS query packet */header.transId = (u_short) rand();header.flags = htons(0x0100);header.questions = htons(0x0001);memset(header.rss, 0, sizeof(header.rss));memcpy(buf, &header, sizeof(header));p = buf + sizeof(header);/* queries: p3-sign.douyinpic.com */p = dns_entry(p, host_name);*p++ = '\0';/* type A, class IN */*p++ = 0x00; *p++ = 0x01;*p++ = 0x00; *p++ = 0x01;queryLen = p - buf;if (send(sockfd, buf, queryLen, 0) < 0) {bclerreg(E_OSCALL, _FL_, "send()");return E_FAIL;}memset(buf, 0, 1024);if (recv(sockfd, buf, 1024, 0) < 1) {bclerreg(E_OSCALL, _FL_, "recv()");return E_FAIL;}p = buf + queryLen;/* Answers: buf + queryLen */TAILQ_INIT(head);while (*p != 0x00) {/* bcl_xxd(p, 0xa0); */if (*(u_char *)p == 0xc0) {/* c0 0c, c0 14 */ans.dataLen = ntohs(((DnsAnswer_t *)p)->dataLen);}
#if DEBUGprintf("dataLen=%d\n", ans.dataLen);bcl_xxd(((DnsAnswer_t *)p)->cname, ans.dataLen);
#endifif (4 == ans.dataLen) { /* IPv4 */memcpy(&ipv4, &((DnsAnswer_t *)p)->cname, 4);n1 = (struct ipv4_entry *)malloc(sizeof(struct ipv4_entry));IPv4_toString(n1->data, ipv4);TAILQ_INSERT_TAIL(head, n1, entries);}p += sizeof(DnsAnswer_t) - HOST_LEN + ans.dataLen;}return E_OK;
}#ifdef __cplusplus
};
#endif
查询DNS以上
C:\Windows\system32\wsl.exe --distribution Ubuntu --exec /bin/bash -c "export ESWTDIR=/mnt/e/CLionProjects/arp && export FAPWORKDIR=/mnt/e/CLionProjects/arp/fap30 && cd /mnt/e/CLionProjects/arp/fap30 && /mnt/e/CLionProjects/arp/cmake-build-debug/arp_test ./input/banner.txt banner_3.jpg"
ip=61.164.142.245
ip=115.231.71.216
path_dst=/mnt/e/CLionProjects/arp/fap30/print/sale.jpg
00000000: 4854 5450 2f31 2e31 2032 3030 204f 4b0d HTTP/1.1 200 OK.
00000010: 0a4c 6173 742d 4d6f 6469 6669 6564 3a20 .Last-Modified:
00000020: 5375 6e2c 2032 3220 4f63 7420 3230 3233 Sun, 22 Oct 2023
00000030: 2030 383a 3036 3a30 3320 474d 540d 0a45 08:06:03 GMT..E
00000040: 7461 673a 2022 3336 3333 3661 6665 3533 tag: "36336afe53
00000050: 3039 6561 3933 6163 6633 3930 6162 3934 09ea93acf390ab94
00000060: 3637 6132 6634 220d 0a43 6f6e 7465 6e74 67a2f4"..Content
00000070: 2d54 7970 653a 2069 6d61 6765 2f6a 7065 -Type: image/jpe
00000080: 670d 0a44 6174 653a 2053 756e 2c20 3232 g..Date: Sun, 22
00000090: 204f 6374 2032 3032 3320 3038 3a30 363a Oct 2023 08:06:
000000a0: 3034 2047 4d54 0d0a 5365 7276 6572 3a20 04 GMT..Server:
000000b0: 7465 6e63 656e 742d 636f 730d 0a78 2d63 tencent-cos..x-c
000000c0: 6f73 2d68 6173 682d 6372 6336 3465 636d os-hash-crc64ecm
000000d0: 613a 2031 3534 3631 3131 3537 3934 3831 a: 1546111579481
000000e0: 3535 3537 3339 340d 0a78 2d63 6f73 2d72 5557394..x-cos-r
000000f0: 6571 7565 7374 2d69 643a 204e 6a55 7a4e equest-id: NjUzN
00000100: 4751 335a 574e 664e 5755 7a4e 6a51 774d GQ3ZWNfNWUzNjQwM
00000110: 474a 664d 5745 305a 4446 664f 5459 314f GJfMWE0ZDFfOTY1O
00000120: 4442 6b4e 673d 3d0d 0a43 6f6e 7465 6e74 DBkNg==..Content
00000130: 2d4c 656e 6774 683a 2032 3237 3938 0d0a -Length: 22798..
00000140: 4163 6365 7074 2d52 616e 6765 733a 2062 Accept-Ranges: b
00000150: 7974 6573 0d0a 582d 4e57 532d 4c4f 472d ytes..X-NWS-LOG-
00000160: 5555 4944 3a20 3735 3537 3138 3835 3632 UUID: 7557188562
00000170: 3130 3431 3837 3231 320d 0a43 6f6e 6e65 104187212..Conne
00000180: 6374 696f 6e3a 206b 6565 702d 616c 6976 ction: keep-aliv
00000190: 650d 0a58 2d43 6163 6865 2d4c 6f6f 6b75 e..X-Cache-Looku
000001a0: 703a 2043 6163 6865 2048 6974 0d0a 0d0a p: Cache Hit....
Process finished with exit code 0
查看下载 E:\CLionProjects\arp\fap30\print\sale.jpg

对于http响应body,有的返回是gzip压缩,要用zlib库解压。分段的内容要解析
/** @ref: https://www.iteye.com/blog/dbscx-830644 */
char *http_chunked_parse(char *s, u_int16_t *len) {int i;/* 0x1000 == 4096 */*len = 0;for (i = 0; i < 4; i++) {if (s[i] == 0x0d && s[i+1] == 0x0a) {break;}/* 32 63 31 0d 0a <=> "3c1\r\n"(LEN=0x2c1, Dec:705) */*len *= 16;if (0x30<=s[i] && s[i] < 0x40) {*len += s[i] - 0x30;} else if (0x61 <= s[i] && s[i] < 0x67) {*len += s[i] - 0x61 + 10;}}if (s[i] == 0x0d && s[i+1] == 0x0a) {s = &s[i] + 2;}return s;
}
0d 0a 30 0d 0a 0d 0a 结束
相关文章:
https下载图片
OpenSSL用法示例 OpenSSL源码安装 对于ubuntu,懒得编译源码可以直接安装 sudo apt-get install libssl–dev /usr/include/openssl/ssl.h CMakeLists中添加 link_libraries(ssl crypto) apt-get安装不需要再制定libssl.a, libcrypto.a的路径了, 就像用libc标…...
二叉树的后续遍历(迭代法)
迭代法实现二叉树的后续遍历 1、递归版本 public static void dfs(TreeNode root){if(rootnull){return;}if(root.left!null)dfs(root.left);if(root.right!null)dfs(root.right);System.out.println(root.val); }从递归版本可以看出我们第一步需要遍历完所有的左节点 这里我…...
CVE-2021-41773/42013 apache路径穿越漏洞
影响范围 CVE-2021-41773 Apache HTTP server 2.4.49 CVE-2021-42013 Apache HTTP server 2.4.49/2.4.50 漏洞原理 Apache HTTP Server 2.4.49版本使用的ap_normalize_path函数在对路径参数进行规范化时会先进行url解码,然后判断是否存在…/的路径穿越符…...
前端性能测试工具WebPagetest
简介:一款web性能在线性能评测工具,可测试有关页面在各种条件下的性能,并且提供深入诊断信息。 WebPagetest 的主页:https://www.webpagetest.org/,也就是工具的使用界面。 注意:WebPageTest 并不是完全免…...
易语言软件定制软件开发脚本开发协议软件电脑网站APP应用视频制作工程制作
随着信息技术的不断发展,易语言软件定制开发已成为许多公司的一项重要业务。本文将探讨如何利用易语言承接软件定制软件开发脚本开发协议软件电脑网站APP应用视频制作工程制作。 一、易语言概述 易语言是一种简单易学的编程语言,它采用中文编程ÿ…...
Windows上配置IP端口转发
在通常涉及到使用网络地址转换(NAT)规则,可以使用一些工具和命令行选项来实现。以下是在Windows上配置端口转发的一般步骤: **注意:端口转发需要管理员权限,因此请确保以管理员身份运行命令行工具。** 1.…...
韦东山D1S板子——汇编启动代码第一行分析(.long 0x0300006f)
1、汇编启动源码 2、分析二进制:0x0300006f 2.1、反汇编代码 2.2、jal指令 jal指令的作用:跳转到当前PC值偏移offset处执行,其中offset由jal指令的bi[31:12]表示; 2.3、分析指令:j 20030 <reset> j 20030 //伪…...
了解单域名证书和通配符证书的区别,选择合适的SSL证书解决方案
随着互联网的不断发展,网站安全性问题一直备受关注,在保护网站数据安全的过程中,SSL证书一直发挥着至关重要的作用。而在选择SSL证书时,单域名证书和通配符证书是两种常见的选择。本文将详细介绍单域名证书和通配符证书的区别&…...
【LeetCode】7. 整数反转
题目链接 文章目录 Python3官方解法 ⟮ O ( ∣ x ∣ ) 、 O ( 1 ) ⟯ \lgroup O(|x|)、O(1)\rgroup ⟮O(∣x∣)、O(1)⟯写法2写法3 C官方解法 ⟮ O ( ∣ x ∣ ) 、 O ( 1 ) ⟯ \lgroup O(|x|)、O(1)\rgroup ⟮O(∣x∣)、O(1)⟯ Python3 官方解法 ⟮ O ( ∣ x ∣ ) 、 O ( 1…...
防止请求重复提交:注解+拦截器的实现方案
文章目录 了解请求重复提交解决思路具体实现 了解请求重复提交 请求重复提交是指用户在一次请求还未处理完成时,重复提交了相同的请求。这种情况通常发生在网络延迟、用户误操作或系统性能不佳等情况下。 请求重复提交可能会导致以下问题和影响: 数据不…...
C#使用mysql-connector-net驱动连接mariadb报错
给树莓派用最新的官方OS重刷了一下,并且用apt install mariadb-server装上“mysql”作为我的测试服务器。然后神奇的事情发生了,之前用得好好的程序突然就报错了,经过排查,发现在连接数据库的Open阶段就报错了。写了个最单纯的Con…...
SpringBoot 定时任务:@EnableScheduling @Scheduled
Scheduled注解参数 cron参数 这个参数是最经常使用的参数,表示接收一个cron参数,cron它是一个表达式,最多接收7个参数,从左到右分别表示:秒 分 时 天 月 周 年;参数以空格隔开,其中年不是必须参…...
Jquery 如何获取子元素。如何找到所有 HTML select 标签的选中项。jQuery 里的 ID 选择器和 class 选择器有何不同
可以使用 jQuery 的子选择器(Child Selector)或 find() 方法来获取子元素。 子选择器(Child Selector): 使用父元素的选择器和 > 符号来选取该父元素的子元素。 例如:选取 id 为 parent 的元素内所有 cl…...
Python Selenium 之数据驱动测试的实现!
数据驱动模式的测试好处相比普通模式的测试就显而易见了吧!使用数据驱动的模式,可以根据业务分解测试数据,只需定义变量,使用外部或者自定义的数据使其参数化,从而避免了使用之前测试脚本中固定的数据。可以将测试脚本…...
【Proteus仿真】【STM32单片机】智能语音家居陪护机器人
文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器,使用OLED显示模块、红外传感器、蜂鸣器、DS18B20温度传感器,风扇LED、语音识别模块等。 主要功能: 系统运行后,…...
C#上位机序列10: 批量读写+点对点更新+数据类型处理
一、源码结构 二、运行效果 三、源码解析 PLC批量读写点对点更新数据类型处理 优点:根据数据类型,判定监听的地址范围(40120_int 监听两个word:40120 40121;40130_long 监听四个word:40130 40131 40132 4…...
MySQL 概述 数据库表操作 数据增删改
目录 MySQL概述前言安装与配置MySQL登录与卸载 数据模型概述SQL简介SQL通用语法简介SQL分类 数据库设计(数据库操作)-DDL数据库操作查询数据库 show databases、select database()创建数据库 create database使用数据库 use删除数据库 drop database 图形化工具连接数据库操作数…...
存储器概述
一、存储系统基本概念...
Fabric.js 使用自定义字体
本文简介 点赞 关注 收藏 学会了 如果你使用 Fabric.js 做编辑类的产品,有可能需要给用户配置字体。 这次就讲讲在 Fabric.js 中创建文本时怎么使用自定义字体、在项目运行时怎么修改字体、以及推荐一个精简字体库的工具。 学习本文前,你必须有一点…...
【C++项目】高并发内存池第七讲性能分析
目录 1.测试代码2.代码介绍3.运行结结果 1.测试代码 #include"ConcurrentAlloc.h" #include"ObjectPool.h" #include"Common.h" void BenchmarkMalloc(size_t ntimes, size_t nworks, size_t rounds) {std::vector<std::thread> vthread(…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
如何在Windows本机安装Python并确保与Python.NET兼容
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...
