WIFI 配网

news2024/12/28 21:10:35

配网:指的是外部向WiFi模块提供SSID和密码,以便Wi-Fi模块可以连接指定的热点
常见的配网方式有:-键配网smart config、SoftAP配网、蓝牙配网、屏幕配网。


1.0 一键配网

 2.0 蓝牙配网

一键配网的模式对应的厂加模式


3.0 状态机WIFI模组物联网


4.0 创建枚举结构体

typedef enum
{
	// 正在处理AT指令
	WIFI_COMM_WAIT,
	// AT 指令接收成功
	WIFI_COMM_OK,
	// AT 指令接收失败
	WIFI_COMM_FALL,
}WifiCommState_t;

5.0 AT指令任务句柄

static WifiCommState_t AtCmdHandle(char *cmd, char *rsp, uint32_t timeoutMs)
{
	static WifiCommState_t s_commState = WIFI_COMM_OK;
	static uint64_t s_sendCmdTime;
	char *recvStrBuf;

	if (s_commState != WIFI_COMM_WAIT)
	{
		if (cmd != NULL)
		{
			SendWifiModuleStr(cmd);			
		}
		s_commState = WIFI_COMM_WAIT;
		s_sendCmdTime = GetSysRunTime();
	}
	else
	{
		if ((GetSysRunTime() - s_sendCmdTime) < timeoutMs)
		{
			recvStrBuf = RecvWifiModuleStr();
			if (strstr(recvStrBuf, rsp) != NULL)
			{
				s_commState = WIFI_COMM_OK;
				ClearRecvWifiStr();
			}
		}
		else
		{
			s_commState = WIFI_COMM_FAIL;
		}
	}
    return s_commState;	
}

注:这个函数的含义是,首先使用if 语句判断是否有命令在处理,在使用if 判断命令是否为空如果命令不为空的话,发送AT指令,使用延时等待函数,同时获取系统当前运行时间。否则获取当前系统时间减去第一次记录时间如果小于规定的时间,发送WIFI指令等...


6.0 AT指令结构体和指令集

typedef struct {
    /* 要发送的AT命令 */
    char *cmd;
    /* 期望的应答数据,默认处理匹配到该字符串认为命令执行成功 */
    char *rsp;
    /* 得到应答的超时时间,达到超时时间为执行失败,单位ms*/
    uint32_t timeoutMs;
} AtCmdInfo_t;

/*模组初始化命令集*/
static AtCmdInfo_t g_checkModuleCmdTable[] = {
	{
        .cmd = "AT+RST\r\n",        // 软复位
        .rsp = "ready",
		.timeoutMs = 3000,
    },
	{
		.cmd = NULL,                 // 只为等待
		.rsp = "XXXXX",
		.timeoutMs = 1000,
	},
    {
        .cmd = "ATE0\r\n",        // 关闭回显
        .rsp = "OK",
		.timeoutMs = 500,
    },
	{
        .cmd = "AT+CWMODE=1\r\n",
        .rsp = "OK",
		.timeoutMs = 500,	
	},
};

7.0 枚举检查AT指令命令类型

typedef enum 
{
	// AT指令硬件复位
	AT_RST,
	// AT指令延时
	AT_RST_DELAY,
	// AT指令回显
    AT_E0,
	// AT指令模式
	AT_CWMODE_1,
} AtCheckModuleCmdType;

8.0 检查WIFI模组工作

WifiCommState_t CheckWifiModuleWork(void)
{
	WifiCommState_t commState;
	static uint8_t retryCount = 0;
	static AtCheckModuleCmdType cmdType = AT_RST;

	switch (cmdType)
	{
		case AT_RST:
			commState = AtCmdHandle(g_checkModuleCmdTable[AT_RST].cmd, g_checkModuleCmdTable[AT_RST].rsp, 
								 g_checkModuleCmdTable[AT_RST].timeoutMs);
		
			if (commState == WIFI_COMM_OK)
			{
				retryCount = 0;
				cmdType = AT_RST_DELAY;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				retryCount++;
				if (retryCount == 3)
				{
					retryCount = 0;
					return WIFI_COMM_FAIL;
				}
			}
			break;
		
		case AT_RST_DELAY:
			commState = AtCmdHandle(g_checkModuleCmdTable[AT_RST_DELAY].cmd, g_checkModuleCmdTable[AT_RST_DELAY].rsp, 
								 g_checkModuleCmdTable[AT_RST_DELAY].timeoutMs);
		
			if (commState == WIFI_COMM_OK)
			{
				cmdType = AT_E0;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				cmdType = AT_E0;
			}
			break;	
			
		case AT_E0:
			commState = AtCmdHandle(g_checkModuleCmdTable[AT_E0].cmd, g_checkModuleCmdTable[AT_E0].rsp, 
								 g_checkModuleCmdTable[AT_E0].timeoutMs);
		
			if (commState == WIFI_COMM_OK)
			{
				retryCount = 0;
				cmdType = AT_CWMODE_1;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				retryCount++;
				if (retryCount == 3)
				{
					retryCount = 0;
					return WIFI_COMM_FAIL;
				}

			}
			break;
		case AT_CWMODE_1:
			commState = AtCmdHandle(g_checkModuleCmdTable[AT_CWMODE_1].cmd, g_checkModuleCmdTable[AT_CWMODE_1].rsp, 
								 g_checkModuleCmdTable[AT_CWMODE_1].timeoutMs);
		
			if (commState == WIFI_COMM_OK)
			{
				cmdType = AT_RST;
				return WIFI_COMM_OK;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				return WIFI_COMM_FAIL;
			}
			break;
	}
	return WIFI_COMM_WAIT;
}

 9.0 检查WIFI状态和WIFI信息

// 检查WIFI连接状态和连接信息
static AtCmdInfo_t g_checkConnectCmdTable[] = 
{
	{
        .cmd = "AT+CWSTATE?\r\n",
        .rsp = "CWSTATE:2",
		.timeoutMs = 1000,	
	},
};


10.0 创建枚举类型

// 创建枚举类型
typedef enum
{
	AT_CWSTATE = 0,
}AtcheckConnectCmdType;

11.0 检查WIFI连接

WifiCommState_t CheckWifiConnect(void)
{
	// 结构体的参数包括WAITE,
	WifiCommState_t commState;
	static AtcheckConnectCmdType cmdType = AT_CWSTATE;
	
	switch(cmdType)
	{
		case AT_CWSTATE:
			commState = AtCmdHandle(g_checkConnectCmdTable[AT_CWSTATE].cmd, g_checkConnectCmdTable[AT_CWSTATE].rsp, 
								 g_checkConnectCmdTable[AT_CWSTATE].timeoutMs);
			if (commState == WIFI_COMM_OK)
			{
				cmdType = AT_CWSTATE;
				return WIFI_COMM_OK;
			}
			else if (commState == WIFI_COMM_FALL)
			{
				return WIFI_COMM_FALL;
			}
			break;
	}
	return WIFI_COMM_WAIT;
}

注:检查WIFI是否连接成功,信息查询 ESP32-C2 设备的 Wi-Fi 状态和 Wi-Fi 信息


12.0 阿里云服务器AT指令信息

const static char g_mqttClientId[] = "k0tp7kBek08.board1|securemode=2\\,signmethod=hmacsha256\\,timestamp=1708571611329|";  
/* 
字符串里\\,第二个\是给at指令用的,第一个\是给编译器用的,不然识别不了第二个\
*/
const static char g_mqttUserName[] = "board1&k0tp7kBek08";
const static char g_mqttPwd[] = "4f777d27c5a22d090d53e47ae8f8b814d129ce64c1bf8bb07529948523e7bf16";
const static char g_mqttUrl[] = "iot-06z00c3kqsjgy5d.mqtt.iothub.aliyuncs.com";


static AtCmdInfo_t g_connectMqttCmdTable[] = {
	{
        .cmd = "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",
        .rsp = "OK",
		.timeoutMs = 500,	
	},
	{
		.cmd = "AT+MQTTCONN=0,\"%s\",1883,1\r\n",
		.rsp = "OK",
		.timeoutMs = 2000,
	},
};

注:以下的这条AT指令用于设置MQTT的用户属性具体参数和格式如下所示:

具体的AT指令如下所示:

AT+MQTTUSERCFG=<LinkID>,<scheme>,<"client_id">,<"username">,<"password">,<cert_key_ID>,<CA_ID>,<"path">

参数按照以下给出的格式进行填写:

  • LinkID>:当前仅支持 link ID 0。

  • <scheme>

    • 1: MQTT over TCP;

    • 2: MQTT over TLS(不校验证书);

    • 3: MQTT over TLS(校验 server 证书);

    • 4: MQTT over TLS(提供 client 证书);

    • 5: MQTT over TLS(校验 server 证书并且提供 client 证书);

    • 6: MQTT over WebSocket(基于 TCP);

    • 7: MQTT over WebSocket Secure(基于 TLS,不校验证书);

    • 8: MQTT over WebSocket Secure(基于 TLS,校验 server 证书);

    • 9: MQTT over WebSocket Secure(基于 TLS,提供 client 证书);

    • 10: MQTT over WebSocket Secure(基于 TLS,校验 server 证书并且提供 client 证书)。

  • <client_id>:MQTT 客户端 ID,最大长度:256 字节。

  • <username>:用户名,用于登陆 MQTT broker,最大长度:64 字节。

  • <password>:密码,用于登陆 MQTT broker,最大长度:64 字节。

  • <cert_key_ID>:证书 ID,目前 ESP-AT 仅支持一套 cert 证书,参数为 0。

  • <CA_ID>:CA ID,目前 ESP-AT 仅支持一套 CA 证书,参数为 0。

  • <path>:资源路径,最大长度:32 字节。


13.0 创建枚举类型

注:内部的成员变量包括检查用户信息和连接MQTT服务器设备

typedef enum 
{
	AT_MQTTUSERCFG = 0,
	AT_MQTTCONN,
} AtConnectMqttCmdType;


14.0 连接MQTT服务

WifiCommState_t ConnectMqttServer(void)
{
	WifiCommState_t commState;
	static uint8_t retryCount = 0;
	static AtConnectMqttCmdType cmdType = AT_MQTTUSERCFG;
	char cmdStrBuf[256] = {0};

	switch (cmdType)
	{
		case AT_MQTTUSERCFG:
			sprintf(cmdStrBuf, g_connectMqttCmdTable[AT_MQTTUSERCFG].cmd, g_mqttClientId, g_mqttUserName, g_mqttPwd);
			commState = AtCmdHandle(cmdStrBuf, g_connectMqttCmdTable[AT_MQTTUSERCFG].rsp, 
								 g_connectMqttCmdTable[AT_MQTTUSERCFG].timeoutMs);
			if (commState == WIFI_COMM_OK)
			{
				cmdType = AT_MQTTCONN;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				return WIFI_COMM_FAIL;
			}
			break;		
		case AT_MQTTCONN:
			sprintf(cmdStrBuf, g_connectMqttCmdTable[AT_MQTTCONN].cmd, g_mqttUrl);
			commState = AtCmdHandle(cmdStrBuf, g_connectMqttCmdTable[AT_MQTTCONN].rsp, 
								 g_connectMqttCmdTable[AT_MQTTCONN].timeoutMs);
			if (commState == WIFI_COMM_OK)
			{
				retryCount = 0;
				cmdType = AT_MQTTUSERCFG;
				return WIFI_COMM_OK;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				retryCount++;
				if (retryCount == 3)
				{
					cmdType = AT_MQTTUSERCFG;
					retryCount = 0;
					return WIFI_COMM_FAIL;
				}
			}
			break;
		default:
			break;
	}
	return WIFI_COMM_WAIT;
}

15.0 发布MQTT消息

const static char g_mqttTopic[] = "/sys/k0tp7kBek08/board1/thing/event/property/post";  // board1对应deviceName,设备名称

static AtCmdInfo_t g_commMqttCmdTable[] = {
	{
        .cmd = "AT+MQTTPUB=0,\"%s\",\"{\\\"params\\\": {\\\"temp\\\": %.1f}}\",0,0\r\n",
        /* 特别注意:转义字符\的数量
		
		   发送的AT命令:
		   AT+MQTTPUB=0,"/sys/k0tp7kBek08/board1/thing/event/property/post","{\"params\": {\"temp\": 10.5}}",0,0\r\n
		*/
		.rsp = "OK",
		.timeoutMs = 500,	
	},
};

注:以下是AT模组参考资料说明

注:注意AT指令格式中 \  的数量

.cmd = "AT+MQTTPUB=0,\"%s\",\"{\\\"params\\\": {\\\"temp\\\": %.1f}}\",0,0\r\n",

注意第一个\ 是给" 使用的第二个是给\使用的,第三个是给编译器使用的如果贸然删除其中的一个会导致指令报错,编译无法通过。


16.0 发布MQTT指令

typedef enum 
{
	AT_MQTTPUB_SENSOR = 0,
} AtCommMqttCmdType;

#define   MQTT_PUB_PERIOD   3000UL    // 上传数据周期,单位ms,不需要太频繁,减少服务器的负担

注:还有一个参数是MQTT指令的时间类型


17.0 传感器数据发布处理

WifiCommState_t CommMqttServer(void)
{
	static WifiCommState_t commState = WIFI_COMM_OK;
	static uint8_t retryCount = 0;
	static AtCommMqttCmdType cmdType = AT_MQTTPUB_SENSOR;
	static uint64_t lastSysTime = 0;
	char cmdStrBuf[256] = {0};
	SensorData_t sensorData;
	
	switch (cmdType)
	{
		case AT_MQTTPUB_SENSOR:
			if (commState != WIFI_COMM_WAIT)
			{
				if ((GetSysRunTime() - lastSysTime) < MQTT_PUB_PERIOD)
				{
					break;
				}
				else
				{
					lastSysTime = GetSysRunTime();
				}
			}
			GetSensorData(&sensorData);
			sprintf(cmdStrBuf, g_commMqttCmdTable[AT_MQTTPUB_SENSOR].cmd, g_mqttTopic, sensorData.temp);
			commState = AtCmdHandle(cmdStrBuf, g_commMqttCmdTable[AT_MQTTPUB_SENSOR].rsp, 
					 g_commMqttCmdTable[AT_MQTTPUB_SENSOR].timeoutMs);
			if (commState == WIFI_COMM_OK)
			{
				retryCount = 0;
				return WIFI_COMM_OK;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				retryCount++;
				if (retryCount == 3)
				{
					cmdType = AT_MQTTPUB_SENSOR;
					retryCount = 0;
					return WIFI_COMM_FAIL;
				}
			}
			break;
		default:
				break;	
	}
	return WIFI_COMM_WAIT;
}


18.0 创建开启SmartConfig结构体数组

static AtCmdInfo_t g_smartCfgCmdTable[] = {
	{
		.cmd = "AT+CWSTARTSMART\r\n", 
		.rsp = "ssid",               // 因为AT+CWSTARTSMART响应有多个包,驱动使用空闲中断,第一包数据包含热点账号密码 
		.timeoutMs = SMART_CONFIG_RECV_SSID_TIMEOUT,
	},
	{
		.cmd = NULL,                 // 因为AT+CWSTARTSMART响应有多个包,驱动使用空闲中断,第三包数据包含"GOT IP",不发送具体命令,只为解析响应
		.rsp = "GOT IP",
		.timeoutMs = SMART_CONFIG_RECV_GOTIP_TIMEOUT,
	},
	{
		.cmd = NULL,                 // 接收到第三包数据包含"GOT IP",等待一会再去发送STOP命令,不然手机侧提示失败,只为等待
		.rsp = "XXXXX",
		.timeoutMs = SMART_CONFIG_DELAY_TIMEOUT,
	},
	{
        .cmd = "AT+CWSTOPSMART\r\n",
        .rsp = "OK",
		.timeoutMs = 300,	
	},
};

注:结构体数组的第一个参数是发送smartConfig命令,第二个参数是接收GOP IP也就是发送命令之后会返回几个数据包这个是其中的一个数据包,第三个参数没有具体的意义是用于实现一个非延时死等的延时方式,第四个参数是结束smartConfig命令的指令。


19.0 创建枚举类型

typedef enum 
{
	// 这个参数表示发送smartConfig
	AT_CWSTARTSMART,
	// 第二个参数表示返回值
	AT_CWSTARTSMART_RECV,
	// 第三个参数表示延时
	AT_CWSTARTSMART_DELAY,
	// 第四个参数表示停止
	AT_CWSTOPSMART,
} AtSmartCfgCmdType;

20.0 创建smartConfig任务处理函数

static WifiCommState_t SmartConfigHandle(void)
{
	WifiCommState_t commState;
	static AtSmartCfgCmdType cmdType = AT_CWSTARTSMART;
	char *recvStrBuf;
	static uint8_t retryCount = 0;
	
	switch (cmdType)
	{
		case AT_CWSTARTSMART:
			commState = AtCmdHandle(g_smartCfgCmdTable[AT_CWSTARTSMART].cmd, g_smartCfgCmdTable[AT_CWSTARTSMART].rsp, 
								 g_smartCfgCmdTable[AT_CWSTARTSMART].timeoutMs);
		
			if (commState == WIFI_COMM_OK)
			{
				recvStrBuf = RecvWifiModuleStr();				
				cmdType = AT_CWSTARTSMART_RECV;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				cmdType = AT_CWSTARTSMART_DELAY;
			}
			break;
		case AT_CWSTARTSMART_RECV:
			commState = AtCmdHandle(g_smartCfgCmdTable[AT_CWSTARTSMART_RECV].cmd, g_smartCfgCmdTable[AT_CWSTARTSMART_RECV].rsp, 
								 g_smartCfgCmdTable[AT_CWSTARTSMART_RECV].timeoutMs);
		
			if (commState == WIFI_COMM_OK)
			{
				cmdType = AT_CWSTARTSMART_DELAY;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				cmdType = AT_CWSTARTSMART_DELAY;
			}
			break;
		case AT_CWSTARTSMART_DELAY:
			commState = AtCmdHandle(g_smartCfgCmdTable[AT_CWSTARTSMART_DELAY].cmd, g_smartCfgCmdTable[AT_CWSTARTSMART_DELAY].rsp, 
								 g_smartCfgCmdTable[AT_CWSTARTSMART_DELAY].timeoutMs);
		
			if (commState == WIFI_COMM_OK)
			{
				cmdType = AT_CWSTOPSMART;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				cmdType = AT_CWSTOPSMART;
			}
			break;
		case AT_CWSTOPSMART:
			commState = AtCmdHandle(g_smartCfgCmdTable[AT_CWSTOPSMART].cmd, g_smartCfgCmdTable[AT_CWSTOPSMART].rsp, 
								 g_smartCfgCmdTable[AT_CWSTOPSMART].timeoutMs);
		
			if (commState == WIFI_COMM_OK)
			{
				retryCount = 0;
				cmdType = AT_CWSTARTSMART;
				return WIFI_COMM_OK;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				retryCount++;
				if (retryCount == 3)
				{
					cmdType = AT_CWSTARTSMART;
					retryCount = 0;
					return WIFI_COMM_FAIL;
				}
			}
			break;
	}
	return WIFI_COMM_WAIT;	
}

注:以上程序代码使用的也是状态机的方式


21.0 创建枚举类型表示WIFI连接的状态

static bool g_needSmartCfg = false;

void StartSmartCfgWifi(void)
{
	g_needSmartCfg = true;
}

static WifiConnectState_t g_wifiConnectState = WIFI_CONNECT_NWK_ING;
WifiConnectState_t GetWifiConnectState(void)
{
	return g_wifiConnectState;
}


typedef enum
{
	CHECK_WIFI_MODULE,
	CHECK_WIFI_CONNECT,
	CONNECT_MQTT_SERVER,
	COMM_MQTT_SERVER,
	SMARTCONFIG_WIFI,
	HWRESET_WIFI_MODULE,
	WIWI_MODULE_ERROR,
} WifiWorkState_t;

22.0 WIFI网络任务函数

void WifiNetworkTask(void)
{
	WifiCommState_t commState;
	static WifiWorkState_t workState = CHECK_WIFI_MODULE;
	static uint8_t hwresetCnt = 0;
	switch (workState)
	{
		case CHECK_WIFI_MODULE:
			g_wifiConnectState = WIFI_CONNECT_NWK_ING;
			commState = CheckWifiModuleWork();
			if (commState == WIFI_COMM_OK)
			{
				workState = CHECK_WIFI_CONNECT;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				workState = HWRESET_WIFI_MODULE;
			}
			break;
		case CHECK_WIFI_CONNECT:
			commState = CheckWifiConnect();
			if (commState != WIFI_COMM_WAIT && g_needSmartCfg)
			{
				workState = SMARTCONFIG_WIFI;
				break;
			}
			if (commState == WIFI_COMM_OK)
			{
				workState = CONNECT_MQTT_SERVER;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				workState = CHECK_WIFI_CONNECT;
			}
			break;		
		case CONNECT_MQTT_SERVER:
			commState = ConnectMqttServer();
			if (commState == WIFI_COMM_OK)
			{
				workState = COMM_MQTT_SERVER;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				workState = CHECK_WIFI_MODULE;
			}
			break;
			
		case COMM_MQTT_SERVER:
			commState = CommMqttServer();
			if (commState != WIFI_COMM_WAIT && g_needSmartCfg)
			{
				workState = SMARTCONFIG_WIFI;
				break;
			}
			if (commState == WIFI_COMM_OK)
			{
				g_wifiConnectState = WIFI_CONNECT_MQTT_SUCESS;
				workState = COMM_MQTT_SERVER;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				g_wifiConnectState = WIFI_CONNECT_MQTT_FAIL;
				workState = CHECK_WIFI_MODULE;
			}
			break;
			
		case SMARTCONFIG_WIFI:
			g_needSmartCfg = false;
			g_wifiConnectState = WIFI_SMART_CONFIGING;
			commState = SmartConfigHandle();
			if (commState == WIFI_COMM_OK)
			{
				workState = CONNECT_MQTT_SERVER;
			}
			else if (commState == WIFI_COMM_FAIL)
			{
				workState = CHECK_WIFI_MODULE;
			}
			break;	
			
		case HWRESET_WIFI_MODULE:
			if (hwresetCnt < 1)                 // 如果AT命令不通,硬件复位1次
			{
				HwresetWifiModule();
				DelayNms(1000);
				workState = CHECK_WIFI_MODULE;
				hwresetCnt++;
			}
			else
			{
				printf("wifi module error!\n");
				workState = WIWI_MODULE_ERROR;  // 如果硬件复位1次,AT命令还是不通,就不再执行WIFI任务的业务逻辑,直接退出,避免影响其他任务
			}
			break;
		default:
			break;
	}
}

注:以上程序使用的也是状态机的思想


23.0 头文件

#ifndef _WIFI_APP_H_
#define _WIFI_APP_H_

#define SMART_CONFIG_RECV_SSID_TIMEOUT   30000
#define SMART_CONFIG_RECV_GOTIP_TIMEOUT  5000
#define SMART_CONFIG_DELAY_TIMEOUT       5000
#define SMART_CONFIG_ENTIRE_TIMEOUT      (SMART_CONFIG_RECV_SSID_TIMEOUT + SMART_CONFIG_RECV_GOTIP_TIMEOUT + SMART_CONFIG_DELAY_TIMEOUT + 5)

typedef enum
{
	WIFI_CONNECT_NWK_ING,
	WIFI_CONNECT_MQTT_FAIL,
	WIFI_CONNECT_MQTT_SUCESS,
	WIFI_SMART_CONFIGING,
} WifiConnectState_t;

void WifiNetworkTask(void);
void StartSmartCfgWifi(void);
WifiConnectState_t GetWifiConnectState(void);
#endif

 

...

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

女性权益之镜:印度侵害事件分析

1.项目背景 近年来&#xff0c;印度社会关于女性权利的讨论日益频繁&#xff0c;然而&#xff0c;女性受侵害的违法事件仍层出不穷&#xff0c;这些事件不仅威胁到女性的生命安全&#xff0c;还深刻影响了社会的稳定与发展&#xff0c;尽管印度政府在法律和政策层面采取了一系…

实现并发网络服务器

一&#xff0c;网络服务器 1.单循环网络服务器 —— 同一时刻只能处理一个客户端任务 2.并发服务器 —— 同一时刻能处理多个客户端任务 二&#xff0c;并发服务器 1.多线程 2.IO多路复用 3.多进程 三&#xff0c;IO模型 1.阻塞IO 阻塞IO&#xff08;Blocking IO&…

IO进程day03(获取文件属性、目录操作、库Lib)

目录 【1】获取文件属性 1》stat函数 2》获取文件类型 3》获取文件权限 练习&#xff1a;编程实现“ls -l 文件名” 的功能 4》stat、fstat、lstat的区别 【2】目录操作 【3】库 Lib 1》文件分类 1> 头文件&#xff1a; 以 .h结尾的文件 2> 源文件&#xff1a…

Qt之控件介绍

目录 控件概述 QWidget核心属性 1.enabled属性 2.geometry属性 3.windowTitle属性 4.windowIcon属性 5.windowOpacity属性 6.cursor属性 7.font属性 8.toolTip属性 9.focusPolicy属性 10.styleSheet属性 按钮类控件&#xff1a; 1.PushButton 2.RadioBu…

Leetcode 17. 电话号码的字母组合 C++实现

Leetcode 17. 电话号码的字母组合 问题&#xff1a;给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 算法&#xff1a;递归嵌…

PyTorch深度学习模型训练流程:(二、回归)

回归的流程与分类基本一致&#xff0c;只需要把评估指标改动一下就行。回归输出的是损失曲线、R^2曲线、训练集预测值与真实值折线图、测试集预测值散点图与真实值折线图。输出效果如下&#xff1a; 注意&#xff1a;预测值与真实值图像处理为按真实值排序&#xff0c;图中呈现…

机器学习概述与应用:深度学习、人工智能与经典学习方法

引言 机器学习(Machine Learning)是人工智能(AI)领域中最为核心的分支之一,其主要目的是通过数据学习和构建模型,帮助计算机系统自动完成特定任务。随着深度学习(Deep Learning)的崛起,机器学习技术在各行各业中的应用变得越来越广泛。在本文中,我们将详细介绍机器学…

Datawhale X 李宏毅苹果书 AI夏令营 Task1笔记

课程内容 学习笔记 &#xff08;一&#xff09;术语解释 一 . 机器学习&#xff08;Machine Learning&#xff0c;ML&#xff09; 机器学习&#xff0c;在本书的解释中是让机器具备找一个函数的能力。个人理解是基于所拥有的数据构建起概率统计模型来对数据进行预测与分析。…

python可视化-散点图

散点图可以了解数据之间的各种相关性&#xff0c;如正比、反比、无相关、线性、指数级、 U形等&#xff0c;而且也可以通过数据点的密度&#xff08;辅助拟合趋势线&#xff09;来确定相关性的强度。另外&#xff0c;也可以探索出异常值&#xff08;在远超出一般聚集区域的数据…

【Java】Record的使用 (简洁教程)

Java系列文章目录 补充内容 Windows通过SSH连接Linux 第一章 Linux基本命令的学习与Linux历史 文章目录 Java系列文章目录一、前言二、学习内容&#xff1a;三、问题描述四、解决方案&#xff1a;4.1 为什么引入Record4.2 Record与Class区别4.3 使用场景 五、总结&#xff1a;…

使用uni-app开发微信小程序

一、前提环境 1.1 &#xff1a;uniapp开发文档&#xff1a;https://uniapp.dcloud.net.cn/quickstart-cli.html 细节都在这一页&#xff0c;这里不过多解释 二、开发工具下载 2.1 微信开发者工具 下载链接&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/dev…

Java:Calendar类

文章目录 Calendar类常用方法代码 黑马学习笔记 Calendar类 calendar是可变对象&#xff0c;一旦修改后其对象本身表示的时间将发生变化 原始对象会跟着修改&#xff0c;造成原始对象的丢失 常用方法 代码 package Time;import java.util.Calendar; import java.util.Date;/…

【RabbitMQ高级特性】消息可靠性原理

1. 消息确认机制 1.1 介绍 我们可以看到RabbitMQ的消息流转图&#xff1a; 当消息从Broker投递给消费者的时候会存在以下两种情况&#xff1a; consumer消费消息成功consumer消费消息异常 如果说RabbitMQ在每次将消息投递给消费者的时候就将消息从Broker中删除&#xff0c…

用 like concat 不用 like,为了防止sql注入;#{}和${}的区别和用法;#{}预防SQL注入的原理

一、like concat 和 like mybatis中为了防止sql注入&#xff0c;使用like语句时并不是直接使用&#xff0c;而是使用concat函数<if test"goodName ! null and goodName ! "> and good_name like concat(%, #{goodName}, %)</if> concat()函数1、功能&a…

Webbench1.5安装使用Ubuntu

1、安装依赖包 sudo apt-get update sudo apt-get install libtirpc-dev2、安装Webbench1.5 参考https://github.com/baiguo/webbench-1.5 # 可能需要root权限&#xff0c;我是切换到root用户才安装成功 wget http://home.tiscali.cz/~cz210552/distfiles/webbench-1.5.tar.…

APP.vue引入子组件进行页面展示

一.将vue项目启动服务器原始页面进行清空 打开APP.vue文件&#xff0c;将<template>标签里的内容和<style>标签里的内容 ctrl/ 选中进行注释&#xff0c;以及引入的Helloworld.vue文件内容代码进行注释 并且 ctrls 保存 服务器页面从原始页面 变为空白 二.在comp…

树莓派4B安装golang最新版(20210520)

前置条件&#xff1a; 树莓派4B 安装官方系统 Linux raspberrypi 5.10.17-v7l #1414 更换最新版的原因&#xff1a; 截至 2021.5.20 &#xff0c;Raspberry Pi OS 最新版系统中&#xff0c;默认安装golang1.11&#xff0c;但是使用 go get golang.org/x/crypto/ssh 时&#xff…

推荐系统实战(七)-多任务多场景(上)多任务

多任务Multi-Task&#xff0c;有时也被称为多目标Multi-Objective建模。比如说电商场景下&#xff0c;希望曝光的物料被多多点击&#xff0c;还希望商品被下单购买&#xff0c;因此同时建模三个目标&#xff1a;曝光到点击CTR&#xff0c;点击到购买转换率CVR&#xff0c;曝光到…

记一次对某佛教系统的漏洞挖掘

前言 简单记录一次漏洞挖掘&#xff0c;一个系统居然爆了这么多类型的洞&#xff0c;于是想记录哈。(比较基础&#xff0c;我是菜狗&#xff0c;大佬轻喷) 业务介绍 是一个某佛教的系统 有一些佛教的学习资源、一些佛教相关的实物商品可购买&#xff0c;有个人中心&#xff…

PyCharm中python语法要求——消去提示波浪线

PyCharm中python语法要求——消去提示波浪线 关闭代码规范检查 在Setting里边搜索pep&#xff0c;取消勾选pep8 coding style violation 问题产生 解决问题 按照下图操作&#xff0c;也可直接CtrlAlts弹出设置页面 在 Settings 中 &#xff1a; Editor > Color Sheame >…