【安全扫描器原理】TCP/IP协议编程
【安全扫描器原理】TCP/IP协议编程
- 1.概述
- 2.Windows Socket结构
- 3.Windows socket转换类函数
- 4.Windows Socket通信类函数
1.概述
TCP/IP协议是目前网络中使用最广泛的协议,Socket称为“套接口”,最早出现在Berkeley Unix中,最初只支持TCP/IP协议族和Unix协议,现在它已支持很多协议,是最重要的网络编程接口
1、端口(Port)和套接口
端口正是我们要扫描的对象,具有“开”和“关”两种状态,利用它的开或关状态就可以初步判断一台主机是否提供了某种服务
和端口所在主机的IP地址结合起来,所形成的一个二元组(IP地址,端口地址)就组成了一个套接口。一个五元组(本地IP、本地端口、使用协议、远程IP、远程端口)组成了一个通信过程
一个IPv4的基本数据结构主要有in_addr
和sockaddr_in
两个,前者表示32位的IP地址,后者是通用的套接口地址结构
// in_addr 是用来表示一个 IPv4 地址(32 位) 的结构体
// s_addr:一个 32 位的整数,表示 IP 地址
struct in_addr {in_addr_t s_addr;
};
struct sockaddr_in {short sin_family; // 地址族,必须是 AF_INET(IPv4)unsigned short sin_port; // 端口号(使用网络字节序)struct in_addr sin_addr; // IPv4 地址char sin_zero[8]; // 填充字段,保持结构体大小一致(通常置为0)
};
2、地址表示顺序
而网络传输中,数据存储顺序不一定和系统存储顺序一样,因此为保证系统正确性和可移植性,需要利用系统的转换函数进行转换。以IPv4的地址为例,一个IP地址的四个字节“192.168.1.100
”,在PC架构的计算机中,数据的表示是低位优先,由前至后是100、1、168、192
;而在网络Socket协议所表示的网络传输中,则是高位优先,由前至后是192、168、1、100
,这需要在处理时通过函数转化
3、面向连接和面向非连接
面向连接(即TCP)的通信的双方,发起连接的为客户端,接收连接的一方称为服务器端。双方的通信一般分三步:建立连接、数据传送、释放连接。在传送过程中数据按顺序传送
面向非连接(即UDP)的通信中,没有客户端和服务器端之分,或者称为互为客户端和服务器端。双方中的任何一方都可以随时向对方发送数据或接收对方的数据
面向连接和面向非连接区别:
- 面向连接的情况下,函数会明确告诉发送成功,但对方未接到;而面向非连接的情况下,函数只是告诉发送成功,不会告诉对方是否接到
- 两台电脑之间连接了一个小时未通信,在面向连接的方式下,这两台电脑之间会不停地发送确认信息以确定链路是否连通;而面向非连接的方式则没有这些维护信息
4、原始套接字
如果不使用原始套接字,则无论是发送和接收,系统都会自动处理IP包头、TCP/UDP包头的数据,这时用户只需要关心发送和接收的数据本身即可。这种自动处理虽然方便,但也使系统失去了灵活性。而当使用原始套接字时,如果发送数据,系统会将要发送的数据包的前面若干字节数据IP头、TCP/UDP头;如果接收数据,系统会将接收到的数据包前面加上数据IP头、TCP/UDP头
2.Windows Socket结构
1、sockaddr结构
该结构用于保存一个IP地址,但这个结构不包含具体协议字段,因此通常不直接使用,而是作为接口参数来传递实际结构(如 sockaddr_in
)
struct sockaddr {unsigned short sa_family; // 地址族(如 AF_INET)char sa_data[14]; // 存放端口号和地址
};
2、sockaddr_in结构
这个结构是IPv4专用的结构,包含了 IP 地址和端口号的具体信息
struct sockaddr_in {short sin_family; // 地址族,一般是 AF_INETunsigned short sin_port; // 端口号(需要用 htons() 转换为网络字节序)struct in_addr sin_addr; // IP 地址char sin_zero[8]; // 补齐用,不使用,需填0
};
其中真正存储IP结构的sin_addr变量又是一个结构,内部是个联合体,有三种访问方式:
struct in_addr {union {struct {unsigned char s_b1, s_b2, s_b3, s_b4;} S_un_b; // 按字节访问IPstruct {unsigned short s_w1, s_w2;} S_un_w; // 按双字节访问IPunsigned long S_addr; // 一般使用这个字段(网络字节序)} S_un;
};
在实际使用中,可以这样访问和赋值:
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8080);
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
有的服务器有多个网卡,此时会有多个IP地址,或是一个网卡配置多个IP地址,而当前的程序并不想只绑定某一个IP地址,这时可以设置S_addr为htonl(INADDR_ANY):
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
3、hostent结构
主要用于存储主机的解析信息,比如域名解析成 IP 后的结果
struct hostent {char *h_name; // 官方主机名(如:www.example.com)char **h_aliases; // 主机别名(一个以NULL结尾的字符串数组)short h_addrtype; // 地址类型(如 AF_INET 表示 IPv4)short h_length; // 地址长度(IPv4是4字节)char **h_addr_list; // 地址列表(每个都是一个 IP 地址的指针)
};
4、servent结构
通常是用于 服务(Service)名到端口号的解析
struct servent {char *s_name; // 服务名称(如 "http")char **s_aliases; // 服务别名(以 NULL 结尾的字符串数组)short s_port; // 端口号(网络字节序)char *s_proto; // 协议名称(如 "tcp" 或 "udp")
};
3.Windows socket转换类函数
1、htons函数
htons函数将计算机存储的USHORT格式转换为网络存储的USHORT格式,16位,一般同于传输端口
网络传输要求所有多字节数值统一为 大端格式(高位在前),以保证跨平台通信一致性。因此,在将端口号等数值用于网络传输前必须调用 htons()
struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(80); // 将主机字节序的端口80转换为网络字节序
server_addr.sin_addr.s_addr = inet_addr("192.168.1.1");
2、ntohs函数
ntohs函数将网络存储的USHORT格式转换为计算机存储的USHORT格式
3、htonl函数
htonl()
主要用于 IP 地址等需要使用 32 位整数传输的场景。将计算机存储的ULONG格式转换为网络存储ULONG格式
4、ntohl函数
ntohl函数将网络存储的ULONG格式转换为计算机存储的ULONG格式,是32位的
5、inet_ntoa函数
inet_ntoa函数将由in_addr结构所表示的网络地址,转换成由字符串表示的IP地址
6、inet_addr函数
inet_addr函数将字符串组成的IP地址串转换成一个ULONG的整数,该整数可用于in_addr结构中,是按网络格式存储的
7、gethostbyname函数
gethostbyname函数根据主机名读取主机的信息(主要是IP地址)
8、gethostbyaddr函数
gethostbyaddr函数通过网络地址读取主机信息
9、gethostname函数
gethostname函数读取本地主机的主机名
10、getservbyname函数
getservbyname函数根据服务名和协议读取服务信息
11、getservbyport函数
getservbyport函数根据端口和协议读取服务信息
4.Windows Socket通信类函数
在使用 Windows Socket 通信类函数时,需要注意以下几点:
- 版本要求:这些函数至少基于 Winsock 1.1 版本或更高版本(如 Winsock 2.2)。在编程时通常使用的是 Winsock 2.x
- 头文件引入:在源文件中需要包含头文件
Winsock2.h
- 链接库设置:在链接阶段需要链接
Ws2_32.lib
静态库,否则编译时会出现未解析的外部符号错误
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
1、WSAStartup函数
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
WSAStartup 用于初始化 Windows Sockets 2(WinSock2)库,它会检查操作系统是否支持所请求的 Socket 版本,并建立底层通信机制。必须最先调用该函数,否则之后的所有 Socket API 都不能使用
程序启动↓
调用 WSAStartup()↓
判断版本支持 & 初始化成功?↓ ↘是 → 继续使用 Socket 否 → 返回错误码(不能使用 WSAGetLastError)
代码案例:
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")int main() {WSADATA wsaData;int result = WSAStartup(MAKEWORD(2, 2), &wsaData);if (result != 0) {printf("WSAStartup failed: %d\n", result);return 1;}// 后续 Socket 操作...WSACleanup(); // 使用完成后清理return 0;
}
2、WSACleanup函数
int WSACleanup(void);
WSACleanup函数完成与socket库绑定的解除,并释放socket库所占用的系统资源。该函数应该作为某次socket操作的最后一个函数,否则之后任何socket操作都会导致出错
3、socket函数
SOCKET socket(int af, int type, int protocol);
socket 函数用于创建一个套接字(Socket),这是网络通信的起点。创建后返回一个套接字描述符(也就是一个“句柄”),用于后续的绑定、监听、发送、接收等操作
参数说明:
代码案例:
SOCKET s = socket(AF_INET, SOCK_STREAM, 0); // 创建一个TCP套接字
if (s == INVALID_SOCKET) {printf("Socket creation failed: %d\n", WSAGetLastError());
}
4、closesocket函数
closesocket关闭之前打开的socket套接字。在进行关闭之前,一般要通过shutdown函数通知对方自己要关闭套接字
5、setsockopt函数
setsockopt 是一个用于设置 socket 参数选项的函数,简单来说,它就是用来“调节” socket 行为的,比如:是否允许端口复用、是否开启 TCP 保活、缓冲区多大等
int setsockopt(SOCKET s, // 要设置的 socket 描述符int level, // 设置的协议级别(SOL_SOCKET/IPPROTO_TCP 等)int optname, // 选项名(SO_REUSEADDR 等)const char *optval, // 选项值的指针int optlen // 选项值的长度
);
调用时机图:
程序启动↓
创建套接字(socket)↓┌────────────────────────────────────┐│ 是否需要更改socket默认参数? │└────────────────────────────────────┘↓ 是 ↓ 否调用 setsockopt 设置参数 继续↓┌────────────────────────────────────┐│ 设置参数是否与 bind 阶段相关? │└────────────────────────────────────┘↓ 是(如SO_REUSEADDR)↓注意调用时机:必须在 bind 之前设置否则 bind 可能失败↓
调用 bind 绑定地址和端口↓
后续 listen / connect 操作
代码案例:使用 setsockopt 设置端口复用(SO_REUSEADDR)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h> // Windows 下 socket 头文件
#pragma comment(lib, "ws2_32.lib") // 链接 ws2_32 库int main() {WSADATA wsaData;SOCKET listenSocket;struct sockaddr_in serverAddr;int opt = 1; // 要设置的选项值int ret;// 初始化 Winsock 库if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {printf("WSAStartup failed: %d\n", WSAGetLastError());return 1;}// 创建 socketlistenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (listenSocket == INVALID_SOCKET) {printf("socket failed: %d\n", WSAGetLastError());WSACleanup();return 1;}// 设置 socket 选项:允许地址复用(端口复用)ret = setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));if (ret == SOCKET_ERROR) {printf("setsockopt failed: %d\n", WSAGetLastError());closesocket(listenSocket);WSACleanup();return 1;}// 准备绑定地址serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定本地任意 IPserverAddr.sin_port = htons(8888); // 绑定端口 8888// 绑定 socketret = bind(listenSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));if (ret == SOCKET_ERROR) {printf("bind failed: %d\n", WSAGetLastError());closesocket(listenSocket);WSACleanup();return 1;}// 开始监听连接ret = listen(listenSocket, SOMAXCONN);if (ret == SOCKET_ERROR) {printf("listen failed: %d\n", WSAGetLastError());closesocket(listenSocket);WSACleanup();return 1;}printf("Server is listening on port 8888...\n");// 清理资源(这里只是简单示例,实际应加入 accept 处理逻辑)closesocket(listenSocket);WSACleanup();return 0;
}
6、select函数
select 用来检测一组 socket 是否就绪(可读、可写或异常),从而避免阻塞或轮询所有 socket,提高程序效率
比如,你写了个服务器,要同时监听100个客户端连接,但你又不想一个个轮询问:“有数据吗?”,这个时候就用 select 让系统帮你监视,哪个 socket 有事发生(有数据可读),就去处理它
int select(int nfds, // Linux 中使用;Windows 忽略fd_set *readfds, // 可读 socket 集合fd_set *writefds, // 可写 socket 集合fd_set *exceptfds, // 异常 socket 集合const struct timeval *timeout // 超时等待时间
);
参数解释:
代码案例,使用 select 等待 socket 可读:
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")int main() {WSADATA wsaData;SOCKET sock;struct sockaddr_in server;fd_set readfds;struct timeval timeout;int ret;WSAStartup(MAKEWORD(2, 2), &wsaData);sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);server.sin_family = AF_INET;server.sin_port = htons(80);server.sin_addr.s_addr = inet_addr("93.184.216.34"); // example.comconnect(sock, (struct sockaddr*)&server, sizeof(server));// 初始化 fd_setFD_ZERO(&readfds);FD_SET(sock, &readfds);// 设置超时时间为5秒timeout.tv_sec = 5;timeout.tv_usec = 0;ret = select(0, &readfds, NULL, NULL, &timeout);if (ret == 0) {printf("Timeout, no data received.\n");} else if (ret < 0) {printf("select error: %d\n", WSAGetLastError());} else {if (FD_ISSET(sock, &readfds)) {printf("Data is available to read.\n");}}closesocket(sock);WSACleanup();return 0;
}
7、bind函数
bind 函数的作用是将 socket 与本地的 IP 地址和端口号绑定起来,这样系统才知道这个 socket 是用哪个本地地址和端口通信的。该函数既可用于面向连接的TCP通信中,也可以用于面向非连接的UDP通信中
int bind(SOCKET s, // 已创建的 socket 描述符const struct sockaddr *name, // 绑定的地址信息int namelen // 地址结构长度
);
案例:
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib") // 链接 Winsock 库int main() {WSADATA wsaData;SOCKET serverSocket;struct sockaddr_in serverAddr;// 初始化 WinsockWSAStartup(MAKEWORD(2, 2), &wsaData);// 创建 TCP socketserverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (serverSocket == INVALID_SOCKET) {printf("Socket creation failed: %d\n", WSAGetLastError());return 1;}// 设置地址信息serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = INADDR_ANY; // 监听所有本地 IPserverAddr.sin_port = htons(8080); // 监听端口 8080// 绑定 socket 和地址if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {printf("Bind failed: %d\n", WSAGetLastError());closesocket(serverSocket);WSACleanup();return 1;}printf("Bind successful on port 8080.\n");// 开始监听连接listen(serverSocket, SOMAXCONN);printf("Listening...\n");WSACleanup();return 0;
}
8、listen函数
listen函数使用socket状态监听状态,并等待其他socket的连接。该函数仅用于面向连接的TCP通信中,UDP通信是不需要listen函数的
int listen(SOCKET s, int backlog);
参数解释:
9、accept函数
accept函数允许和接收一个远端的连接,该函数仅用于面向连接的TCP通信中,并且只用于服务器端,用于接收客户端通过connect函数发来的连接申请;面向非连接的UDP通信是不需要处理此函数的
可以把 listen 比喻成“门卫准备好了”,而 accept 就是“打开门迎客”那一刻
SOCKET accept(SOCKET s, struct sockaddr *addr, int *addrlen);
参数解释:
该函数看似简单,其实比较复杂,也是多线程处理效果的关键,首先调用此函数之前,应该已成功地调用了listen函数。然后在调用该函数时,如果调用成功,则返回一个新的socket,所以如果后面服务端的处理很简单,可以在当前线程中用这个新创建的socket进行处理,俗称“短连接”;
如果处理很复杂,并且仍在当前线程中处理,则会影响到accept函数对其他线程通过connect进行连接,此时就需要再创建一个线程,由新建的线程,并使用返回的一个socket专门处理此次连接后的各项操作,俗称“长连接”
代码案例:TCP服务端
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")int main() {WSADATA wsaData;SOCKET listenSocket, clientSocket;struct sockaddr_in serverAddr, clientAddr;int clientAddrLen = sizeof(clientAddr);WSAStartup(MAKEWORD(2, 2), &wsaData);// 创建 TCP socketlistenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);// 绑定 IP + 端口serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = INADDR_ANY;serverAddr.sin_port = htons(8080);bind(listenSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));// 启动监听listen(listenSocket, SOMAXCONN);printf("Server is listening on port 8080...\n");// 接受客户端连接(阻塞)clientSocket = accept(listenSocket, (SOCKADDR*)&clientAddr, &clientAddrLen);if (clientSocket == INVALID_SOCKET) {printf("Accept failed: %d\n", WSAGetLastError());closesocket(listenSocket);WSACleanup();return 1;}printf("Accepted a connection from %s:%d\n",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));// 发送欢迎消息const char* welcomeMsg = "Hello, client!\n";send(clientSocket, welcomeMsg, strlen(welcomeMsg), 0);// 关闭连接closesocket(clientSocket);closesocket(listenSocket);WSACleanup();return 0;
}
10、connect函数
在扫描器的应用中,connect是一种简单而有效的连接方式,连接成功,则可以认为对方的端口是打开的。该函数仅用于面向连接的TCP通信中,并且只用于服务器端,用来接收客户端通过connect函数发来的连接申请;面向非连接的UDP通过是不需要处理此函数的
11、send函数
send函数发送数据到已建立连接的socket上,该函数既可以用于服务器端,也可以用于客户端,但双方都必须是采用TCP连接
12、recv函数
recv函数用于接收从已建立连接的socket上的数据,该函数既可以用于服务器端,也可以用于客户端,但双方都必须是采用TCP连接。
13、shutdown函数
shutdown 函数用于关闭某个方向上的数据传输通道:只收、不收、只发、不发,或者两个方向都关。更优雅、明确地通知对方“我不想再发/收数据了”,避免连接状态混乱
int shutdown(SOCKET s, int how);
参数说明:
how 参数的取值:
如果直接调用 closesocket(s)
而不 shutdown
:
- 对方可能还在写入你的 socket,但你这边已经关掉了,数据就丢了;
- 没有给 TCP 协议一个“四次挥手” 的机会,可能造成资源悬挂(TIME_WAIT 状态不一致);
正确关闭流程应该是:
shutdown(socket, SD_SEND); // 发送结束,通知对方
recv(...); // 等对方把剩下要说的说完
closesocket(socket); // 最后关闭 socket
14、sendto函数
sendto函数发送数据报到远端的主机指定的端口上。该函数只能用于面向非连接的通信中
15、recvfrom函数
recvfrom函数接收远端发过来的数据报。该函数只能用于面向非连接的通信中
相关文章:
【安全扫描器原理】TCP/IP协议编程
【安全扫描器原理】TCP/IP协议编程 1.概述2.Windows Socket结构3.Windows socket转换类函数4.Windows Socket通信类函数 1.概述 TCP/IP协议是目前网络中使用最广泛的协议,Socket称为“套接口”,最早出现在Berkeley Unix中,最初只支持TCP/I…...
Cuda-GDB Frame Unwind 管理(未完.)
在计算机编程中,Frame Unwind(栈展开) 是指函数调用栈的逆向操作,即在函数返回或异常发生时,系统逐层释放栈帧(Stack Frame)、恢复调用上下文的过程。以下是详细解释及其在 GPU编程(…...
如何在IDEA中高效使用Test注解进行单元测试?
在软件开发过程中,单元测试是保证代码质量的重要手段之一。而IntelliJ IDEA作为一款强大的Java开发工具,提供了丰富的功能来支持JUnit测试,尤其是通过Test注解可以快速编写和运行单元测试。那么,如何在IDEA中高效使用Test注解进行…...
什么是访客鉴权?全面解析核心原理与CC防护应用实践
一、访客鉴权是什么? 访客鉴权(Visitor Authentication and Authorization)是系统对访问者进行身份验证和权限控制的过程,确保只有合法用户能够访问特定资源或执行特定操作。其核心目标是确认身份、控制权限、保障数据安全&#…...
DeepSeek大模型应用学习通知
随着人工智能在各领域深度融合发展,DeepSeek大模型迅速火爆全网,清华大学以最快的速度发布了DeepSeek从入门到精通使用技巧,能够更好的助力于企业和个人参与到AI研究和应用中,对于AI行业创新有重要意义,被誉为国运级的…...
时间序列预测模型比较分析:SARIMAX、RNN、LSTM、Prophet 及 Transformer
时间序列预测根据过去的模式预测未来事件。我们的目标是找出最佳预测方法,因为不同的技术在特定条件下表现出色。本文章将探讨各种方法在不同数据集上的表现,为你在任何情况下选择和微调正确的预测方法提供真知灼见。 我们将探讨五种主要方法࿱…...
快速了解redis,个人笔记
更多个人笔记:(仅供参考,非盈利) gitee: https://gitee.com/harryhack/it_note github: https://github.com/ZHLOVEYY/IT_note (基于mac展示,别的可以参考)接下来将直接…...
Dify依赖管理poetry切换为uv
Dify升级 1.3.0 后api的依赖管理从poetry切换为了 uv管理,但是官网暂时还没有更新。 升级 tag:Dify 1.3.0版本 在此记录一下 uv 依赖管理操作 使用方法 [重要事项] 在 v1.3.0 版本中,poetry 已被[ uv ](https://docs.astral.sh/uv/) 替代…...
VGA 接口静电防护方案
VGA(Video Graphics Array)即视频图形阵列,具有分辨率高、显示速 率快、颜色丰富等优点,亦称为 D-Sub 接口,在彩色显示器领域得到了广 泛的应用, 如笔记本、投影仪、LCD 液晶显示屏 等。VGA 接口主要用于连接 计算机与显示设备。当…...
MySQL 详解之用户、权限与审计:保障数据安全的基石
在数据库系统中,数据是核心资产,对其的访问必须受到严格控制。谁能连接到数据库?他们能看到哪些数据?能执行哪些操作(读、写、修改结构)?系统中的所有操作是否被记录以便追溯?这正是用户管理、权限系统和审计机制需要解决的问题。 在 MySQL 中: 用户 (Users): 负责认…...
力扣面试150题--环形链表和两数相加
Day 32 题目描述 思路 采取快慢指针 /*** Definition for singly-linked list.* class ListNode {* int val;* ListNode next;* ListNode(int x) {* val x;* next null;* }* }*/ public class Solution {public boolean hasCycle(ListNod…...
HMI与组态,自动化的“灵珠”和“魔丸”
在现代工业自动化领域,组态(Configuration)和人机界面(HMI,Human-Machine Interface)是两个核心概念,它们在智能化控制系统中发挥着至关重要的作用。尽管这两者看似简单,但它们的功能…...
AbMole| CU-CPT-8m(CAS号125079-83-6;目录号M9746)
CU-CPT-8m是一种特异性的TLR8(toll-like receptor 8)拮抗剂,其IC50值为67 nM,Kd值为220 nM。 生物活性 CU-CPT-8m是一种特异性的TLR8(toll-like receptor 8)拮抗剂,其IC50值为67 nM,…...
【网络入侵检测】基于源码分析Suricata的PCAP模式
【作者主页】只道当时是寻常 【专栏介绍】Suricata入侵检测。专注网络、主机安全,欢迎关注与评论。 1. 概要 👋 本文聚焦于 Suricata 7.0.10 版本源码,深入剖析其 PCAP 模式的实现原理。通过系统性拆解初始化阶段的配置流程、PCAP 数据包接收线程的创建与运行机制,以及数据…...
【滑动窗口+哈希表/数组记录】Leetcode 438. 找到字符串中所有字母异位词
题目要求 给定两个字符串 s 和 p,找到 s 中所有 p 的异位词的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 字母异位词是通过重新排列不同单词或短语的字母而形成的单词或短语,并使用所有原字母一次。 示例 1 输入:s…...
uniapp自定义封装tabbar
uniapp自定义封装tabbar 开发原因: 有很多时候 小程序并没有其类目 需要通过配置发布审核, ps:需要去掉项目pages.json tabbar配置,不然重进会显示默认,跳转页面不能uni.switchTab。 组件tabbar <template><viewclass&…...
uni-app云开发总结
uni-app云开发总结 云开发无非就三个概念:云数据库、云函数、云存储 uni-app中新增了一个概念叫做云对象,它其实就是云函数的加强版,它是导出的一个对象,对象中可以包含多个操作数据库的函数,接下来咱们就详细对uni-…...
uniapp-商城-37-shop 购物车 选好了 进行订单确认3 支付栏
支付栏 就是前面用的 car-Layout 在shop也用来这个组件 只是在那里用来的是购物车。 1、 样式 我们开始进入这个页面是点击的shop的购物篮 到这里就变成了支付栏 其实他们是同一个组件 只是做了样式区分 2、具体看看样式和代码 2.1 消失了购物车和改变了按钮名字 如何…...
搜索二叉树-key的搜索模型
二叉搜索树(Binary Search Tree, BST)是一种重要的数据结构,它有两种基本模型:Key模型和Key/Value模型。 一、Key模型 1.基本概念 Key模型是二叉搜索树中最简单的形式,每个节点只存储一个键值(key),没有额外的数据值(value)。这…...
Qt ModbusSlave多线程实践总结
最近项目中用到了ModbusSlave,也就是Modbus从设备的功能,之前用的基本都是master设备,所以读取数据啥的用单线程就行了,用 void WaitHelper::WaitImplByEventloop(int msec) {QEventLoop loop;QTimer::singleShot(msec, &loop…...
Leetcode刷题记录18——接雨水
题源:https://leetcode.cn/problems/trapping-rain-water/description/?envTypestudy-plan-v2&envIdtop-100-liked 题目描述: 思路一: 🌟 本题核心思想:木桶效应 每个位置的“桶”:假设每个柱子的位…...
IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤
以下是在 IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤: 步骤 1:创建 Maven Web 项目 新建项目 File -> New -> Project → 选择 Maven → 勾选 Create from archetype → 选择 maven-archetype-webapp。输入 GroupId(如 com.examp…...
全球玻璃纸市场深度洞察:环保浪潮下的材料革命与产业重构(2025-2031)
一、行业全景:从传统包装到绿色经济的战略支点 玻璃纸(Cellulose Film),即再生纤维素薄膜,以木浆、棉浆等天然纤维素为原料,通过碱化、黄化、成型等工艺制成,兼具透明性、柔韧性及100%生物降解性…...
提示js方法未定义,但是确实<textarea>标签未闭合。
1、问题现象。 Uncaught ReferenceError: showOtherDismantleFn is not defined 但是这个方法,在代码中明明存在。 #if($!{isNewEnergy})#if($!{batteryName} 宁德时代)<button class"btn btn-info btn-xs" onclick"showNingDismantleFn()&quo…...
spring中的@bean注解详解
在Spring框架中,Bean注解是用于显式声明一个Bean的核心方式之一,尤其在基于Java的配置中。Spring框架中的Bean注解实现原理涉及多个核心机制,包括配置类解析、Bean定义注册、动态代理及依赖注入等 一、Bean注解的作用 Bean用于标注在方法上&…...
计算机网络中的DHCP是什么呀? 详情解答
目录 DHCP 是什么? DHCP 的工作原理 主要功能 DHCP 与网络安全的关系 1. 正面作用 2. 潜在安全风险 DHCP 的已知漏洞 1. 协议设计缺陷 2. 软件实现漏洞 3. 配置错误导致的漏洞 4. 已知漏洞总结 举例说明 DHCP 与网络安全 如何提升 DHCP 安全性 总结 D…...
uniapp-商城-38-shop 购物车 选好了 进行订单确认4 配送方式1
配送方式在订单确认页面最上方,可以进行选中配送还是自提,这里先看看配送。 代码样式: 可以看出来是通过组件来实现的。组件名字是:delivery-layout 1、建立组件文件夹和页面,delivery-layout这里就只有配送 2、具体…...
粒子群优化算法(Particle Swarm Optimization, PSO)的详细解读
最近研究基于进化算法的神经网络架构搜索,仔细阅读了TEVC2023年发表的一篇NAS搜索的文章,觉得收益颇多,对比NSGA-2,这里给出PSO的详细解释。【本人目前研究的是多目标进化算法,欢迎交流、留言】 文章题目是࿱…...
大模型在直肠癌预测及治疗方案制定中的应用研究
目录 一、引言 1.1 研究背景与意义 1.2 研究目的 1.3 研究方法与创新点 二、大模型技术概述 2.1 大模型的基本原理 2.2 常见大模型类型及特点 2.3 在医疗领域的应用进展 三、直肠癌预测相关数据收集与处理 3.1 数据来源 3.2 数据清洗与预处理 3.3 特征工程 四、大…...
【C++】继承----下篇
文章目录 前言一、实现一个不能继承的类二、友元与继承三、继承与静态成员四、多继承以及菱形继承问题1.继承模型:2.菱形继承的问题3.虚拟继承解决数据冗余和二义性的原理4.虚拟继承的原理 五、继承的总结和反思1.继承和组合 总结 前言 各位好呀!今天呢我们接着讲继…...
windows安装jax和jaxlib的教程(cuda)成功安装
本文你将解决3个问题:1、jaxlib没有安装的问题;2、python3.9以上(不可忽略)、cuda12.1(可忽略)以上配置要求不满足的问题;3、numpy版本太高的问题。 1、问题描述 当你直接pip install jax或者c…...
软考【网络工程师】2023年5月上午题答案解析
1、固态硬盘的存储介质是()。 A 光盘 B 闪存 C 软盘 D 磁盘 答案是 B。 固态硬盘(Solid State Drive),简称 SSD,是用固态电子存储芯片阵列制成的硬盘,其存储介质是闪存(Flash Memory)。闪存具有非易失性,即在断电后仍能保留存储的数据,且读写速度快、抗震性强、能…...
支付场景下,乐观锁的实现(简洁版)
1、问题描述 看到一个同事建的数据库表,好奇打开看看。 create table db_paycenter.t_pay_order_divide (id bigint auto_increment comment 主键id|20250402|XXXprimary key,user_id bigint not null comment user…...
AI视频技术赋能幼儿园安全——教师离岗报警系统的智慧守护
教师离岗报警系统如一位无形的守护者,实时监测教室动态,一旦发现教师离岗超30秒,立即通知园方,确保幼儿不被忽视。这套开源系统以高效检测和即时报警为核心,助力园所优化管理,增强家长信心,开启…...
SCI论文结构笔记
摘要五要素(Abstract): 背景和研究问题研究目的研究方法研究结果结论和意义 引言(Introduction): 研究背景研究问题研究现状现有的研究的问题与不足本研究的研究目标文章结构 研究综述(Literature review): 选题的理由现存文献中可借鉴的…...
《修仙家族模拟器2》:游戏背景故事介绍!
《修仙家族模拟器2》构建了一个以修仙文明为根基的宗族传承世界,玩家将扮演家族初代掌舵者,在动态演变的修仙江湖中完成从凡俗世家到仙道巨擘的蜕变。以下为具体背景设定解析: 一、世界观架构:仙凡交织的修真宇宙 空间维度 游戏…...
Linux部署ragflow,从安装docker开始~
安装docker https://download.docker.com/linux/static/stable/x86_64/docker-28.0.1.tgz #首先创建一个文件夹,存放我们需要的各类文件,并切换到该目录 mkdir /project && cd /project #此时我们的工作目录已经切换到刚刚创建的文件夹下了,接…...
苹果iosApp提交审核常见问题--内购订阅篇
常见问题1- 准则2.1.1 Guideline 2.1 - Information Needed The app binary includes the PassKit framework for implementing Apple Pay, but we were unable to verify any integration of Apple Pay within the app. Next Steps If the app integrates the functionali…...
从代码学习深度学习 - 微调 PyTorch 版
文章目录 前言一、迁移学习与微调概念二、微调步骤解析三、实战案例:热狗识别3.1 数据集准备3.2 图像增强处理3.3 加载预训练模型3.4 模型重构3.5 差异化学习率训练3.6 对比实验分析总结前言 深度学习模型训练通常需要大量数据,但在实际应用中,我们往往难以获得足够的标记数…...
Registry镜像仓库的安装与使用
任务目标 (1)了解目前主流的镜像仓库 (2)掌握registry私有镜像仓库的部署与使用 任务实施 基础信息 Docker私有仓库个宿主机配置信息 主机名 IP地址 节点角色 registry 192.168.110.80 私有仓库 node1 192.168.110.9…...
java多线程(6.0)
目录 编辑 阻塞队列 阻塞队列概念 生产者消费者模型 阻塞队列的作用 阻塞队列的使用 阻塞队列的实现 阻塞队列 阻塞队列概念 阻塞队列是一种特殊的队列,同样遵循“先进先出”的原则,支持入队操作和出队操作和一些基础方法。在此基础上&#…...
tkinter的文件对话框:filedialog
诸神缄默不语-个人技术博文与视频目录 文章目录 一、前言二、tkinter.filedialog模块详解2.1 模块导入方式2.2 通用参数说明 三、五大核心函数实战3.1 选择单个文件 - askopenfilename()3.2 多文件选择 - askopenfilenames()3.3 保存文件对话框 - asksaveasfilename()3.4 选择目…...
HOW - 如何模拟实现 gpt 展示答案的交互效果
文章目录 产品设计维度核心目标实现方式主要靠一些技巧1. 用 emoji 做语义锚点2. 每个段落只传达一件事3. 有节奏地对话式切换4. 使用 Markdown 风格来排版5. 用“你”而不是“用户”说话 如果想实现类似体验(比如写文档、教程、产品介绍) 前端开发维度想…...
达梦数据库压力测试报错超出全局hash join空间,适当增加HJ_BUF_GLOBAL_SIZE解决
1.名词解释:达梦数据库中的HJ_BUF_GLOBAL_SIZE是所有哈希连接操作可用的最大哈希缓冲区大小,单位为兆字节(MB) 2.达梦压测报错: 3.找到达梦数据库安装文件 4.压力测试脚本 import http.client import multiprocessi…...
第11章 面向分类任务的表示模型微调
第1章 对大型语言模型的介绍第2章 分词和嵌入第3章 解析大型语言模型的内部机制第4章 文本分类第5章 文本聚类与主题建模第6章 提示工程第7章 高级文本生成技术与工具第8章 语义搜索与检索增强生成第9章 多模态大语言模型第10章 构建文本嵌入模型第12章 微调生成模…...
c#加密证件号的中间部分,改为*号
前言 使用场景:在我项目中,我需要给前端提供接口,所以我要吧证件号进行加密。例如:411421199510225612,这是一个身份证号,18为的,那么我加密完成之后就会是 411421********5612,类似…...
qt中写一个简易的计算器
以下是添加了详细代码注释的版本: cpp #include <iostream>using namespace std;定义加法函数(已注释掉) //int add(int a, int b) { // return a b; //}定义减法函数(已注释掉) //int min(int a, int b) {…...
[特殊字符] Docker 从入门到实战:全流程教程 + 项目部署指南(含镜像加速)
Docker 是现代 DevOps 的基石,应用广泛于微服务、CI/CD、K8s、云原生等场景。本文将从 0 到 1 手把手带你掌握 Docker 的核心知识点,并完成 Java Nginx 项目部署,适合新手与进阶开发者阅读与实战。 📚 目录 Docker 快速入门 入门…...
《R语言SCI期刊论文绘图专题计划》大纲
今天开始,我将和大家分享系统且详细的《R语言SCI期刊绘图专题教程》,内容会从基础到高阶应用,从配色美学到顶刊风格复现,确保大家可以学到高质量内容!下面是大纲。 📚《R语言SCI期刊论文绘图专题计划》 第…...
从氛围到节奏:情绪化配乐网站指南
在影视、短视频、广告甚至游戏开发中,配乐的作用早已超越了简单的背景音效,它能够深刻地影响观众的情绪,为作品注入灵魂。但如何找到那些能够精准传达情绪、完美契合画面的配乐呢?今天,就让我们一起探索那些能够助力你…...