Linux--网络编程
一、网络编程概述
1.进程间通信:
1)进程间通信的方式有**:管道,消息队列,共享内存,信号,信号量这么集中
2)特点:依赖于linux内核,基本是通过内核来实现应用层的两个进程间的通信
3)缺陷:无法多机通讯
2.网络编程:
1)网络编程适用去不同的pc间的通信,可以实现多机运行
2)它关心的是:地址和数据
地址是指:IP地址和端口号。每台PC机连网够都有一个IP地址,那么每台联网的PC机可能跑多个服务器,然后每个服务器中对应的有很多进程。当客户端接入的时候,不知道去对接哪个服务器。那么这时端口号对应的就是每个服务器的端口。客户就可以通过端口号连接到对应的服务器了。
数据是指:协议(HTTP/TCP/UDP)
它是一种数据格式
3.TCP/UDP对比
1)TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2)TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大的努力交付,即不保证可靠交付
3)TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的,UDP没用拥塞控制,因此网络出现拥塞不会使源主机的发送速率减低(对实时应用很有用,如IP电话,实时视频会议等)
4)每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5)TCP首部开销字节;UDP的首部开销小,只有8字节
6)TCP的逻辑通信信道是全双工的可靠信道;UDP则是不可靠信道
4.端口号的作用
一台拥有IP地址的主机可以提供许多服务,比如Web服务,FTP服务,SMTP服务
这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务的呢?显然不能只靠IP地址,因为IP地址和网络服务的关系是一对多的关系。
实际上是通过“IP地址+端接口”来区分不同服务的。
端口提供了一种访问通道,
服务器一般都是通过知名端口号来识别的。例如,对于每个TCP/IP实现来说,FTP服务器的TCP端口号都是21,每个Telnet服务器的TCP端口号都是23,每个TFTP(简单文件传送协议)服务器的UDP端口号都是69
二、字节序
1.定义
字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。
2.常见序
1)Little endian(小端字节序):将低序字节存储在起始地址
LE little-endian
最符合人的思维的字节序
地址低位存储值的低位
地址高位存储值的高位
怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说
低位值小,就应该放在内存地址小的地方,也即内存地址低位
反之,高位值就应该放在内存地址大的地方,也即内存地址高位
2) Big endian(大端字节序):将高序字节存储在起始地址
BE big-endian
最直观的字节序
地址低位存储值的高位
地址高位存储值的低位
为什么说直观,不要考虑对应关系
只需要把内存地址从左到右按照由低到高的顺序写出
把值按照通常的高位到低位的顺序写出
两者对照,一个字节一个字节的填充进去
三、socket编程步骤
1.创建套接字
函数原型:
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
domain:
指明所使用的协议族,通常为AF_INET,表示互联网协议族(TCP/IP协议族)
AF_INET IPv4 因特网域
AF_INET6 IPv6 因特网域
AF_UNIX Uinx 域
AF_ROUTE 路由套接字
AF_KEY 密匙套接字
AF_UNSPEC 未指定
type参数指定socket的类型:
SOCK_STREAM:
流式套接字提供可靠的,面向连接的通信流;它使用TCP协议,从而保证了数据传输的正确性和顺序性
SOCK_DGRAM:
数据报套接字定义了一种无连接的服,数据通过相互独立的报文传输,是无序了,并且不保证是可靠,无差错的。它使用数据包协议UDP
SOCK_RAW:
允许程序使用底层协议,原始套接字允许对底层协议如IP或ICMP进行直接访问,功能强大但使用较为不便,主要用于一些协议的开发
protocol:
通常赋值:0
0选择type类型对应的默认协议
IPPROTO_TCP TCP传输协议
IPPROTO_UDP UDP传输协议
IPPROTO_SCTP SCTPC传输协议
IPPROTO_TIPC TIPC传输协议
2.bind()函数:IP端口号与相应描述字赋值函数
函数原型:
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:
用于绑定IP地址和端口号到socketfd
参数:
sockfd
是一个socket描述符
addr
是一个指向包含有本机IP地址及端口号等信息的sockaddr类型的指针,指向要绑定给sockfd的协议地址结构,这个地址结构根据地址创建socket时的地址协议族的不同而不同addrlen
addr
指向的结构体的大小,以字节为单位
struct sockaddr *addr:一般用替换的:
ipv4对应的是:
struct sockaddr {sa_family_t sa_family;//协议族char sa_data[14];//IP+端口号}同等替换:
struct sockaddr_in{sa_family_t sin_family;//协议族in_port_t sin_port;//端口号struct in_addr sin_addr;//IP地址结构体unsigned char sin_zero[8];//填充,没用实际意义,只是为sockaddr结构在内存中对齐,这样两者才能相互转换}
地址转换API
//把字符串形式“127.0.0.1”转化为网络能识别的格式
int inet_aton(const char* straddr,struct in_addr *addrp);//把网络格式的IP地址转化为字符串形式
char* inet_ntoa(struct in_addr sin_addr);
将主机字节顺序转换为网络字节顺序
网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。
为了进行转换 bsd socket提供了转换的函数 有下面四个
htons 把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序
在使用little endian的系统中 这些函数会把字节序进行转换
在使用big endian类型的系统中 这些函数会定义成空宏
同样 在网络程序开发时 或是跨平台开发时 也应该注意保证只用一种字节序 不然两方的解释不一样就会产生bug.
htonl()函数
头文件
#include <arpa/inet.h>
htonl()函数
函数原型是:uint32_t htonl(uint32_t hostlong)
1.hostlong是主机字节顺序表达的32位数,htonl中的h–host主机地址,to–to,n–net网络,l–unsigned long无符号的长整型(32位的系统是4字节);
2.函数返回值是一个32位的网络字节顺序;
3.函数的作用是将一个32位数从主机字节顺序转换成网络字节顺序。
htons()函数
函数原型是:uint16_t htons(uint16_t hostlong)
1.hostlong是主机字节顺序表达的16位数,htons中的h–host主机地址,to–to,n–net网络,s–short long无符号的短整型(32位的系统是2字节);
2.函数返回值是一个16位的网络字节顺序;
3.函数的作用是将一个16位数从主机字节顺序转换成网络字节顺序,简单的说就是把一个16位数高低位呼唤。
ntohs()函数
函数原型是:uint16_t ntohs(uint16_t hostlong)
1.hostlong是网络字节顺序表达的16位数,ntohs中的,n–net网络,to–toh–host主机地址,s–short long有符号的短整型(32位的系统是2字节);
2.函数返回值是一个16位的主机字节顺序;
3.函数的作用是将一个16位数由网络字节顺序转换为主机字节顺序,简单的说就是把一个16位数高低位互换。
ntohl()函数
函数原型是:uint32_t ntohs(uint32_t hostlong)
1.hostlong是网络字节顺序表达的32位数,ntohs中的,n–net网络,to–toh–host主机地址,s–unsigned long无符号的短整型(32位的系统是4字节);
2.函数返回值是一个32位的主机字节顺序;
3.函数的作用是将一个32位数由网络字节顺序转换为主机字节顺序。
大小端
比如: unsigned long hostlong = 0xa2b4c6d8;
大端顺序存放:
偏移地址 存放内容
0x00000000 0xa2
0x00000001 0xb4
0x00000002 0xc6
0x00000003 0xd8
小端顺序存放:
偏移地址 存放内容
0x00000000 0xd8
0x00000001 0xc6
0x00000002 0xb4
0x00000003 0xa2
网络字节顺序一定是大端顺序,主机字节不一定
3.监听
listen()函数:监听设置函数
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>int listen(int sockfd, int backlog);
功能:
设置能处理的最大连接数,listen() 并未开始接收连接,只是设置socket 的 listen 模式,listen 函数只用于服务端,服务器进程不知道要与谁连接,因此,它不会主动要求与某个进程连接,只是一直监听是否有其他客户进程与之连接,然后响应该连接请求,并对他做出处理,一个服务进程可以同时处理多个客户进程的连接。主要就两个功能:将一个未连接的套接字转换为一个被动的套接字(监听),规定内核为相应套接字排队的最大连接数。
内核为任何一个给定监听套接字维护两个队列:
未完成连接队列,每个这样的SYN 报文段对应其中一项:已由某个客户端发出并到达服务器,而服务器正在等待完成相应的TCP 三次握手过程。这些套接字处于SYN_REVD 状态;
已完成连接队列,每个已完成TCP 三次握手过程的客户端对应其中一项。这些套接字处于ESTABLISHED 状态;
参数
sockfd
sockfd 是socket 系统调用返回的服务器端socket 描述符
backlog
backlog 指定在请求队列中允许的最大请求数
4.接受连接
accept()函数
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:
accept 函数由TCP 服务器调用,用于从已完成连接队列对头返回下一个已完成连接。如果已完成连接队列为空,那么进程被投入睡眠。
参数:
sockfd
sockfd 是socket 系统调用返回的服务器端(s_addr)socket 描述符
addr
用来返回已连接的对端(客户端)的协议地址
addrled
客户端大小(c_addr)
返回值:
该函数的返回值是一个新的套接字描述符,返回值是表示已连接的套接字描述符,而第一个参数是服务器监听套接字描述符。一个服务器通常仅仅创建一个监听套接字,它在该服务器的生命周期内一直存在。内核为每个由服务器进程接收的客户连接创建一个已连接套接字(表示TCP 三次握手已完成),当服务器完成对某个给定客户的服务器时,相应的已连接套接字就会被关闭。
5.数据的收发:
字节流读取函数
在套接字通信中进行字节读取函数:read(); write(); 与I/O 中的读取读取函数略有区别,因为它们输入或输出的字节数比可能比请求的要少。
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t recv(int sockfd, void *buf, size_t len, int flags);
注意:这里fd文字描述符就是套接字。。
6.客户端的connect函数:
connect()函数:客户连接主机
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能:
该函数用于绑定之后的client 端(客户端),与服务器建立连接
参数:
sockfd:是目的服务器的socket 描述符
addr:是服务器端的IP 地址和端口号的地址结构指针
addrlen:地址长度,常被设置为sizeof(struct sockaddr)
返回值:
成功返回0,遇到错误时返回 -1,并且error中包含相应的错误码
7.网络消息代码:
1.服务器代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>int main()
{int s_fd;char readbuf[128] = {0};int nread;char *msg = "I get your message,QINGYuan is handsome.\n";struct sockaddr_in s_addr;struct sockaddr_in c_addr;memset(&s_addr,0,sizeof(struct sockaddr_in));memset(&c_addr,0,sizeof(struct sockaddr_in));
//1.sockets_fd = socket(AF_INET,SOCK_STREAM,0);if(s_fd == -1){perror("socket");exit(-1);
}//2.binds_addr.sin_family = AF_INET;s_addr.sin_port = htons(8989);inet_aton("192.168.1.71",&s_addr.sin_addr);bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));//3.listenlisten(s_fd,10);//4.acceptint clen = sizeof(struct sockaddr_in);int c_fd = accept(s_fd,(struct sockaddr*)&c_addr,&clen);if(c_fd == -1){perror("accept");exit(-1);}printf("start conneting...\n");sleep(2);printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));//5.readnread = read(c_fd,readbuf,128);if(nread == -1){perror("read");}else{printf("get message :%d,%s\n",nread,readbuf);
}//6.writeif(write(c_fd,msg,strlen(msg))<0){perror("write");exit(-1);
}return 0;}
运行结果:
客户端代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>int main()
{int c_fd;char readbuf[128];int nread;char *msg="msg from client\n";struct sockaddr_in c_addr;memset(&c_addr,0,sizeof(struct sockaddr_in));//1.socketc_fd=socket(AF_INET,SOCK_STREAM,0);if(c_fd==-1){perror("socket");exit(-1);}//2.connectc_addr.sin_family=AF_INET;c_addr.sin_port=htons(8989);inet_aton("192.168.1.5",&c_addr.sin_addr);if(connect(c_fd,(struct sockaddr*)&c_addr,sizeof(struct sockaddr))==-1){perror("connect");exit(-1);}//3.writewrite(c_fd,msg,strlen(msg));//4.readnread=read(c_fd,readbuf,128);if(nread==-1){perror("read");}else{printf("get message from sever:%d,%s\n",nread,readbuf);}return 0;
}
2.多个客户端连接代码:
服务器代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>int main(int argc,char **argv)
{int s_fd;char readbuf[128];int nread;int mark=0;char msg[128]={0};struct sockaddr_in s_addr;struct sockaddr_in c_addr;if(argc!=3){printf("param is not good\n");exit(-1);}memset(&s_addr,0,sizeof(struct sockaddr_in));memset(&c_addr,0,sizeof(struct sockaddr_in));//1.sockets_fd=socket(AF_INET,SOCK_STREAM,0);if(s_fd==-1){perror("socket");exit(-1);}//2.binds_addr.sin_family=AF_INET;s_addr.sin_port=htons(atoi(argv[2]));inet_aton(argv[1],&s_addr.sin_addr);bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));//3.listenlisten(s_fd,10);//4.acceptint clen=sizeof(struct sockaddr_in);while(1){int c_fd=accept(s_fd,(struct sockaddr*)&c_addr,&clen);if(c_fd==-1){perror("accept");}printf("connect\n");mark++;sleep(2);printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));if(fork()==0){if(fork()==0){while(1){memset(msg,0,sizeof(msg));sprintf(msg,"welcome No.%d client",mark);//6.writewrite(c_fd,msg,strlen(msg));sleep(3);}}while(1){//5.readmemset(readbuf,0,sizeof(readbuf));nread=read(c_fd,readbuf,128);if(nread==-1){perror("read");}else{printf("get message:%d,%s\n",nread,readbuf);}}break;} }return 0;
}
客户端代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>int main()
{int s_fd;char readbuf[128] = {0};int nread;char *msg = "I get your message,QINGYuan is handsome.\n";struct sockaddr_in s_addr;struct sockaddr_in c_addr;memset(&s_addr,0,sizeof(struct sockaddr_in));memset(&c_addr,0,sizeof(struct sockaddr_in));
//1.sockets_fd = socket(AF_INET,SOCK_STREAM,0);if(s_fd == -1){perror("socket");exit(-1);
}//2.binds_addr.sin_family = AF_INET;s_addr.sin_port = htons(8989);inet_aton("192.168.1.71",&s_addr.sin_addr);bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));//3.listenlisten(s_fd,10);//4.acceptint clen = sizeof(struct sockaddr_in);int c_fd = accept(s_fd,(struct sockaddr*)&c_addr,&clen);if(c_fd == -1){perror("accept");exit(-1);}printf("start conneting...\n");sleep(2);printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));//5.readnread = read(c_fd,readbuf,128);if(nread == -1){perror("read");}else{printf("get message :%d,%s\n",nread,readbuf);
}//6.writeif(write(c_fd,msg,strlen(msg))<0){perror("write");exit(-1);
}return 0;}
结果:
相关文章:

Linux--网络编程
一、网络编程概述1.进程间通信: 1)进程间通信的方式有**:管道,消息队列,共享内存,信号,信号量这么集中 2)特点:依赖于linux内核,基本是通过内核来实现应用层…...

数据结构 并查集
作用 快速的处理以下问题:【近乎O(1)的时间完成】 1.将两个集合合并 2.询问两个元素是否在一个集合中 用树的形式维护集合 基本原理 每一个集合用一棵树表示 每一个集合的编号就是根结点的编号,对于每一个结点,都存储其父结点…...

算法通关村第十六关黄金挑战——求滑动窗口中的最大值(滑动窗口与堆方法、双端队列法和直接比较法)
大家好,我是怒码少年小码。 今天这篇就讲一道题目,不难😎,但是一定要学会自己思考。 滑动窗口最大值 LeetCode 239:给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。…...

常见树种(贵州省):009楠木、樟木、桂木种类
摘要:本专栏树种介绍图片来源于PPBC中国植物图像库(下附网址),本文整理仅做交流学习使用,同时便于查找,如有侵权请联系删除。 图片网址:PPBC中国植物图像库——最大的植物分类图片库 一、楠木 …...

全志H616开发版
开发板介绍: 二、开发板刷机 SDFormatter TF卡的格式化工具、Win32Diskimager 刷机工具 刷机镜像为:Orangepizero2_2.2.0_ubuntu_bionic_desktop_linux4.9.170.img 使用MobaXterm_Personal_20.3连接使用 网络配置:nmcli dev wifi 命令接入网…...

【Spring boot】RedisTemplate中String、Hash、List设置过期时间
文章目录 前言Redis中String设置时间的方法Redis中Hash和List设置时间的方法Redis中Hash的put、putAll、putIfAbsent区别 前言 时间类型:TimeUnit import java.util.concurrent.TimeUnit;TimeUnit.SECONDS:秒 TimeUnit.MINUTES:分 TimeUnit.HOURS&…...

Nosql之redis概述及基本操作
关系数据库与非关系型数据库概述 关系型数据库 关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录。SQL语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型…...

使ros1和ros2的bag一直互通
很多文章都是先source ros1 然后source ros2,再play bag source /opt/ros/noetic/setup.bash source /opt/ros/foxy/setup.bash ros2 bag play -s rosbag_v2 kitti_raw00.bag 但实测会出问题: 为使ros1和ros2的bag一直互通 sudo apt update sudo apt install ros-foxy-ro…...

【正点原子 linux 驱动编程】
在此声明,正用点编的说明书真的拉,丝毫不具备兼容性。。比如linux的第一个实验,其中包含的 unregister_chrdev_region 函数,fileoperation 结构体等均来自 <linux/fs.h> 文件,搞不懂,他们方ide.h&…...

使用Python的turtle模块绘制玫瑰花图案(含详细Python代码与注释)
1.1引言 turtle模块是Python的标准库之一,它提供了一个绘图板,让我们可以在屏幕上绘制各种图形。通过使用turtle,我们可以创建花朵、叶子、复杂的图案等等。本博客将介绍如何使用turtle模块实现绘制图形的过程,并展示最终结果。 …...

Redis学习笔记14:基于spring data redis及lua脚本ZSET有序集合实现环形结构案例及lua脚本如何发送到redis服务器
案例实现目标,一、实现一个环形结构,环形结构上节点有一个阀值threshold,超过阀值则移除分数score最低的成员,不足则将当前成员添加进环中,且确保成员不可重复;二、每次访问环中的数据都需要刷新key的过期时间…...

openssl C++研发之pem格式处理详解
一、PEM_writeXXX和EM_write_bio_XXX 在OpenSSL的crypto/pem.h头文件中,PEM_write_XXXX和PEM_write_bio_XXXX系列函数用于将特定类型的数据写入文件或BIO(内存缓冲区)中,其中XXXX代表不同的数据类型。 这些函数的使用方式相似&a…...

【教3妹学编辑-mysql】详解数据库三大范式
什么是范式 简单地理解就是:数据库设计时遵循的规范 三大范式 数据库三大范式包含:1、第一范式(1NF);2、第二范式(2NF);3、第三范式(3NF)。其中,第一范式(1NF)的要求是属性不可分割,第二范式(2NF)的要求是…...

【计算机网络笔记】路由算法之链路状态路由算法
系列文章目录 什么是计算机网络? 什么是网络协议? 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能(1)——速率、带宽、延迟 计算机网络性能(2)…...

读像火箭科学家一样思考笔记04_第一性原理(下)
1. 来自无形规则的阻力 1.1. 无形规则 1.1.1. 僵化成规则的不必要习惯和行为 1.1.2. 不像有形的书面规则 1.1.2.1. 书面规则出现在标准操作流程中,可以修改或删除 1.1.3. 成文的规则可能会抗拒变革,但无形规则却更加顽固 1.1.4. 我们为强加在自己身…...

开源集群管理系统对比分析:Kubernetes 与 Apache Mesos
集群管理系统是关键的软件解决方案,可以在互连机器网络中有效分配和利用计算资源。毫无疑问,它们通过确保可扩展性、高可用性和有效的资源管理在现代计算中发挥着至关重要的作用,这使得它们对于运行复杂的应用程序、管理数据中心以及进一步增…...

matlab 坡度滤波算法地面分割
目录 一、算法原理1、实现流程2、参考文献二、代码实现三、结果展示四、测试数据一、算法原理 1、实现流程 1、格网示意图 2、计算格网行列数 公式中的特殊符号为向上取整,...

【腾讯云 HAI域探秘】高性能服务器引领AI革新浪潮:从AI绘画、知识问答到PyTorch图像分类、视频检测的全方位探索
目录 1 HAI(高性能应用服务)简介2 HAI的应用场景2.1 HAI在AI作画中的灵活性与效率2.2 深入探索LLM语言模型的应用与性能2.3 HAI支持的AI模型开发环境与工具 3 基于stable difussio的AI 绘画应用实践3.1 使用AI模型中的stable diffusion模型服务3.2 设置和…...

【Java】ExcelWriter自适应宽度工具类(支持中文)
工具类 import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet;/*** Excel工具类** author xiaoming* date 2023/11/17 10:40*/ public class ExcelUti…...

C++二分查找算法:132模式枚举3简洁版
本文涉及的基础知识点 二分查找算法合集 本题不同解法 包括题目及代码C二分查找算法:132 模式解法一枚举3C二分查找算法:132 模式解法二枚举2代码简洁C二分查找算法:132 模式解法三枚举1性能最佳C单调向量算法:132 模式解法三枚…...

Map 和 WeakMap:JavaScript 中的键值对集合
JavaScript 是一种动态、弱类型的脚本语言,经常用于构建现代 Web 应用程序。在编写 JavaScript 代码时,我们经常需要使用各种数据结构来存储和管理数据。其中,Map 和 WeakMap 就是两个非常有用的数据结构,它们分别提供了用于存储键…...

linux rsyslog综合实战1
本次我们通过rsyslog服务将A节点服务器上的单个日志(Path:/var/log/245-1.log)实时同步到B节点服务器目录下(Path:/opt/rsyslog/245) 1.rsyslog架构 2.环境信息 环境信息 HostnameIpAddressOS versionModuleNotersyslog1192.168.10.245CentOS Linux release 7.9.2009 (Core)rs…...

redis+python 建立免费http-ip代理池;验证+留接口
前言: 效果图: 对于网络上的一些免费代理ip,http的有效性还是不错的;但是,https的可谓是凤毛菱角; 正巧,有一个web可以用http访问,于是我就想到不如直接拿着免费的HTTP代理去做这个! 思路: 1.单页获取ipporttime (获取time主要是为了后面使用的时候,依照时效可以做文章) 2.整…...

虚幻C++ day5
角色状态的常见机制 创建角色状态设置到UI上 在MainPlayer.h中新建血量,最大血量,耐力,最大耐力,金币变量,作为角色的状态 //主角状态UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category "Playe Stats&…...

C#中的DateTime类
C# 中的 DateTime 类是用于表示日期和时间的结构。它提供了一系列属性和方法,用于处理日期和时间的各种操作和计算。下面是一些常用的 DateTime 类的用法和方法解释,以及相应的示例说明: 创建 DateTime 对象: 使用当前日期和时间创…...

Flutter笔记:Matrix4矩阵变换与案例
Flutter笔记 Matrix4矩阵变换及其案例 作者:李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 :291148484163.com 本文地址:https://blog.csdn.net/qq_28550263/article/details/134474764 【简介…...

数字IC前端学习笔记:时钟切换电路
相关阅读 数字IC前端https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 有些时候我们需要在系统运行时切换系统时钟,最简单的方法就是使用一个MUX(数据选择器)选择输出的时钟,如下代码片所…...

.NET6使用MiniExcel根据数据源横向导出头部标题及数据
.NET6MiniExcel根据数据源横向导出头部标题 MiniExcel简单、高效避免OOM的.NET处理Excel查、写、填充数据工具。 特点: 低内存耗用,避免OOM、频繁 Full GC 情况 支持即时操作每行数据 兼具搭配 LINQ 延迟查询特性,能办到低消耗、快速分页等复杂查询 轻量…...

表内容的操作(增删查改)【MySQL】
文章目录 表的 CRUDCreate(增加)插入记录插入冲突则更新记录替换记录 Retrieve(查找)查找记录指定表达式的别名为结果去重WHERE 子句运算符条件查询区间查询模糊查询空值查询 对结果排序筛选分页结果 Update(修改&…...

C++快速入门 - 2(几分钟让你快速入门C++)
C快速入门 - 2 1. 内联函数1.1 概念1.2 特性 2. auto关键字(C11)2.1 类型别名思考2.2 auto简介2.3 auto的使用细则2.4 auto不能推导的场景 3. 基于范围的for循环(C11)3.1 范围for的语法3.2 范围for的使用条件 1. 内联函数 1.1 概念 以inline修饰的函数叫做内联函数,…...