C语言通过IXMLHTTPRequest以get或post方式发送http请求获取服务器文本或xml数据

做过网页设计的人应该都知道ajax。
Ajax即Asynchronous Javascript And XML(异步的JavaScript和XML)。使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。
在IE浏览器中,Ajax技术就是基于JavaScript里面的XMLHTTPRequest。AJAX通过XMLHttpRequest对象发出HTTP 请求,得到服务器返回的数据后,再进行处理。现在,服务器返回的都是JSON格式的数据,XML格式已经过时了,但是AJAX这个名字已经成了一个通用名词,字面含义已经消失了。
XMLHttpRequest对象是AJAX的主要接口,用于浏览器与服务器之间的通信。尽管名字里面有XML和Http,它实际上可以使用多种协议(比如file或ftp),发送任何格式的数据(包括字符串和二进制)。

其实,不仅在网页上能用JavaScript语言调用XMLHTTPRequest组件,在桌面窗口程序里面也可以用C语言或C++调用XMLHTTPRequest组件。
XMLHTTPRequest是微软msxml6.0里面的组件。msxml6.0可直接解析服务器返回的xml文档,但json数据需要在网上找cJSON库来解析。

首先我们要在自己的服务器上准备好处理ajax请求的页面,本文准备了三个示例页面:str_test.php、json_test.php和xml_test.php,分别用来产生文本回应、json回应和xml回应。xml_test.php页面支持get和post两种ajax请求方式。

PHP文件用UTF-8编码保存,但C文件要用GB2312编码保存。
这是因为在微软的简体中文Windows系统里面,以A结尾的API函数(如CreateWindowA)采用的是GB2312编码的char *字符串,以W结尾的API函数(如CreateWindowW)采用的是UTF-16编码的wchar_t *字符串,COM组件使用的BSTR字符串是在wchar_t *字符串的基础上增加了4字节的字符串长度前缀。
IXMLHttpRequest组件(一种COM组件)工作时使用的是UTF-16编码的BSTR字符串。
我们在收到IXMLHttpRequest组件提供的UTF-16编码的BSTR字符串后,如果想要用printf在控制台上打印出来,就需要用convert_bstr_to_string函数将BSTR转换为GB2312编码的char *字符串。想要直接打印BSTR字符串不能用printf函数,要用WriteConsoleW函数才行。如果是显示在窗口的文本框或者窗口的标题栏上那就简单了,直接用SetWindowTextW或SetDlgItemTextW函数,把BSTR字符串传进去就行了。
同样,在给IXMLHttpRequest组件传递字符串参数时,需要先用convert_string_to_bstr函数将GB2312编码的char *字符串转换为UTF-16编码的带长度前缀的BSTR字符串。
如果是写入txt文本文件的话,我们就可以采用UTF-8编码,用MultiByteToWideChar函数(CP_UTF8)将BSTR转换成UTF-8编码的char *字符串,再用fprintf或fwrite写入txt文件。

str_test.php:

<?php header('Content-type: text/html; charset=utf-8'); ?>
当前时间为<?=date("Y年n月j日 H:i:s")?>。

 json_test.php:

<?php
header('Content-type: application/json');
header('Pragma: no-cache');
header('Cache-control: no-cache');
header('Expires: 0');

$arr = array();
$arr["date"] = date("Y-n-j H:i:s");
$arr["time"] = time();
$arr["desc"] = "abcd简体中文";
echo json_encode($arr);
?>

xml_test.php:

<?php
header('Content-type: text/xml');

session_start();
header('Pragma: no-cache');
header('Cache-control: no-cache');
header('Expires: 0');

echo '<?xml version="1.0" encoding="utf-8"?>';
$timestr = strftime("%Y%m%d%H%M%S");
echo "<test timestr=\"$timestr\" example=\"简体中文\">";
foreach ($_COOKIE as $name => $value) {
	$_name = htmlspecialchars($name);
	$_value = htmlspecialchars($value);
	echo "<cookie name=\"$_name\">$_value</cookie>";
}
foreach ($_GET as $name => $value) {
	$_name = htmlspecialchars($name);
	$_value = htmlspecialchars($value);
	echo "<param method=\"get\" name=\"$_name\">$_value</param>";
}
foreach ($_POST as $name => $value) {
	$_name = htmlspecialchars($name);
	$_value = htmlspecialchars($value);
	echo "<param method=\"post\" name=\"$_name\">$_value</param>";
}
echo '</test>';
?>

下面我们来看看C语言如何像网页里面那样用XMLHTTPRequest发送ajax请求。

/* 这个程序只能在C编译器下编译成功, 请确保源文件的扩展名为c */
#define COBJMACROS
#include <stdio.h>
#include <MsXml6.h>

#pragma comment(lib, "msxml6.lib")

// char *转BSTR
// 用完后调用SysFreeString释放
BSTR convert_string_to_bstr(const char *s)
{
	int n;
	wchar_t *ws;
	BSTR bstr = NULL;

	n = MultiByteToWideChar(CP_ACP, 0, s, -1, NULL, 0);
	ws = malloc(n * sizeof(wchar_t));
	if (ws != NULL)
	{
		MultiByteToWideChar(CP_ACP, 0, s, -1, ws, n);
		bstr = SysAllocString(ws);
		free(ws);
	}
	return bstr;
}

// BSTR转char *
// 用完后调用free释放
char *convert_bstr_to_string(BSTR bstr)
{
	char *s;
	int n;

	n = WideCharToMultiByte(CP_ACP, 0, bstr, -1, NULL, 0, NULL, NULL);
	s = malloc(n);
	if (s != NULL)
		WideCharToMultiByte(CP_ACP, 0, bstr, -1, s, n, NULL, NULL);
	return s;
}

// 去掉字符串末尾的\r\n
void remove_last_crlf(char *str)
{
	int len;

	len = (int)strlen(str);
	if (len >= 2 && str[len - 2] == '\r' && str[len - 1] == '\n')
		str[len - 2] = '\0';
}

// 示例: 读取纯文本内容 (同步方式)
void str_test(const char *url)
{
	char *response;
	long status;
	BSTR method_bstr, url_bstr, response_bstr;
	HRESULT hr;
	IXMLHTTPRequest *xhr;
	VARIANT async; // VARIANT代表一个弱类型的变量
	VARIANT null;

	hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLHTTPRequest, &xhr);
	if (SUCCEEDED(hr))
	{
		// 打开连接
		// get参数内容是放到url字符串里面的
		method_bstr = convert_string_to_bstr("GET");
		url_bstr = convert_string_to_bstr(url);
		async.vt = VT_BOOL;
		async.boolVal = VARIANT_FALSE; // 选择非异步方式 (也就是同步方式)
		null.vt = VT_NULL;
		hr = IXMLHttpRequest_open(xhr, method_bstr, url_bstr, async, null, null); // 最后两个参数是用户名和密码, 不用填
		SysFreeString(method_bstr);
		SysFreeString(url_bstr);
		if (SUCCEEDED(hr))
			printf("open() succeeded\n");

		// 发送请求
		// 由于我们选择的是同步方式, 所以send函数要等到所有数据都接收完了才返回
		hr = IXMLHttpRequest_send(xhr, null); // 第二个参数是post数据内容, 不用管
		if (SUCCEEDED(hr))
			printf("send() succeeded\n");

		// 获取请求状态
		// 0: open函数还没调用
		// 1: send函数还没调用
		// 2: send函数调用了, get_status()函数已经可以使用了, 也可以读http headers了, 但是还读不了response
		// 3: 已收到了部分数据, 可以读responseBody和responseText
		// 4: 所有数据都已经接收完了, responseBody和responseText已经是完整数据了
		hr = IXMLHttpRequest_get_readyState(xhr, &status);
		if (SUCCEEDED(hr))
			printf("ready state: %d\n", status);

		// 获取http返回的response code
		hr = IXMLHttpRequest_get_status(xhr, &status);
		if (SUCCEEDED(hr))
			printf("http status code: %d\n", status);

		// 读取并显示文本内容
		hr = IXMLHTTPRequest_get_responseText(xhr, &response_bstr);
		if (SUCCEEDED(hr))
		{
			// response_bstr是utf16编码, 转换后的response是gb2312编码
			// 把函数里面的CP_ACP改成CP_UTF8就可以转成utf8编码, 但是utf8就没办法用printf打印, 只能用fwrite写入txt文件再用记事本打开查看
			response = convert_bstr_to_string(response_bstr);
			remove_last_crlf(response);
			printf("response: %s\n", response);
			free(response);
			SysFreeString(response_bstr);
		}

		IXMLHttpRequest_Release(xhr);
	}
	printf("\n");
}

// 直接显示xml代码
void display_xmlstr(IXMLDOMDocument *xmldoc)
{
	char *str;
	BSTR bstr;
	HRESULT hr;

	hr = IXMLDOMDocument_get_xml(xmldoc, &bstr);
	if (SUCCEEDED(hr))
	{
		str = convert_bstr_to_string(bstr);
		remove_last_crlf(str);
		printf("xmlstr: %s\n", str);
		free(str);
		SysFreeString(bstr);
	}
}

// 显示xml属性值
void display_attr(IXMLDOMElement *elem, const char *name)
{
	char *value;
	BSTR bstr; // 表示一个带长度前缀的utf16编码的字符串
	VARIANT variant; // 表示一个弱类型的变量

	bstr = convert_string_to_bstr(name);
	IXMLDOMElement_getAttribute(elem, bstr, &variant);
	SysFreeString(bstr); // 使用完字符串后必须释放

	if (variant.vt == VT_BSTR)
	{
		value = convert_bstr_to_string(variant.bstrVal);
		printf("%s: %s\n", name, value);
		free(value);
		SysFreeString(variant.bstrVal); // 保存在Variant中的BSTR也必须释放掉
	}
	else if (variant.vt == VT_NULL)
		printf("%s: (null)\n", name);
}

// 检查xml节点名称是否为指定名称
int check_node_name(IXMLDOMNode *node, const char *expected_name)
{
	char *name;
	int ret;
	BSTR bstr;

	IXMLDOMNode_get_nodeName(node, &bstr);
	name = convert_bstr_to_string(bstr);
	SysFreeString(bstr);

	ret = (strcmp(name, expected_name) == 0);
	free(name);
	return ret;
}

// 检查xml属性值是否为指定值
int check_node_attr(IXMLDOMNode *node, const char *attr, const char *expected_value)
{
	char *value;
	int ret = 0;
	BSTR bstr;
	HRESULT hr;
	IXMLDOMElement *elem;
	VARIANT variant;

	IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMElement, &elem); // 先把node转成element
	bstr = convert_string_to_bstr(attr);
	hr = IXMLDOMElement_getAttribute(elem, bstr, &variant); // 再通过element获取属性值
	SysFreeString(bstr);
	if (SUCCEEDED(hr))
	{
		if (variant.vt == VT_BSTR)
		{
			value = convert_bstr_to_string(variant.bstrVal);
			ret = (strcmp(value, expected_value) == 0);
			SysFreeString(variant.bstrVal);
			free(value);
		}
		else if (variant.vt == VT_NULL)
			ret = (expected_value == NULL || expected_value[0] == '\0');
	}
	IXMLDOMElement_Release(elem);
	return ret;
}

void display_xml(IXMLDOMDocument *xmldoc)
{
	char *text;
	long i, len;
	BSTR text_bstr;
	HRESULT hr;
	IXMLDOMElement *root;
	IXMLDOMNode *node;
	IXMLDOMNodeList *list;

	IXMLDOMDocument_get_documentElement(xmldoc, &root);
	display_attr(root, "timestr");
	display_attr(root, "example");
	display_attr(root, "title");

	hr = IXMLDOMElement_get_childNodes(root, &list);
	if (SUCCEEDED(hr))
	{
		IXMLDOMNodeList_get_length(list, &len);
		for (i = 0; i < len; i++)
		{
			IXMLDOMNodeList_get_item(list, i, &node);
			if (check_node_name(node, "param") && check_node_attr(node, "method", "get") && check_node_attr(node, "name", "txt"))
			{
				IXMLDOMNode_get_text(node, &text_bstr);
				text = convert_bstr_to_string(text_bstr);
				printf("txt: %s\n", text);
				free(text);
				SysFreeString(text_bstr);
			}
			else if (check_node_name(node, "param") && check_node_attr(node, "method", "post") && check_node_attr(node, "name", "hello"))
			{
				IXMLDOMNode_get_text(node, &text_bstr);
				text = convert_bstr_to_string(text_bstr);
				printf("hello: %s\n", text);
				free(text);
				SysFreeString(text_bstr);
			}
			IXMLDOMNode_Release(node);
		}
		IXMLDOMNodeList_Release(list);
	}
	IXMLDOMElement_Release(root);
}

// 示例: 读取xml内容 (同步方式)
void xml_test(const char *url, const char *post_data)
{
	long status;
	BSTR method_bstr, url_bstr, header_bstr, value_bstr;
	HRESULT hr;
	IDispatch *disp;
	IXMLDOMDocument *xmldoc;
	IXMLHTTPRequest *xhr;
	VARIANT async;
	VARIANT body;
	VARIANT null;

	hr = CoCreateInstance(&CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLHTTPRequest, &xhr);
	if (SUCCEEDED(hr))
	{
		if (post_data == NULL)
			method_bstr = convert_string_to_bstr("GET");
		else
			method_bstr = convert_string_to_bstr("POST");
		printf("method: %ls\n", method_bstr); // 不带中文的BSTR可直接用%ls输出, 带中文就不行了

		url_bstr = convert_string_to_bstr(url);
		async.vt = VT_BOOL;
		async.boolVal = VARIANT_FALSE;
		null.vt = VT_NULL;
		hr = IXMLHttpRequest_open(xhr, method_bstr, url_bstr, async, null, null);
		SysFreeString(method_bstr);
		SysFreeString(url_bstr);
		if (SUCCEEDED(hr))
			printf("open() succeeded\n");

		if (post_data == NULL)
			body = null;
		else
		{
			header_bstr = convert_string_to_bstr("Content-Type");
			value_bstr = convert_string_to_bstr("application/x-www-form-urlencoded");
			IXMLHttpRequest_setRequestHeader(xhr, header_bstr, value_bstr);
			SysFreeString(header_bstr);
			SysFreeString(value_bstr);

			body.vt = VT_BSTR;
			body.bstrVal = convert_string_to_bstr(post_data);
		}
		hr = IXMLHttpRequest_send(xhr, body);
		if (SUCCEEDED(hr))
			printf("send() succeeded\n");
		if (body.vt == VT_BSTR)
		{
			SysFreeString(body.bstrVal);
			body = null;
		}

		hr = IXMLHttpRequest_get_readyState(xhr, &status);
		if (SUCCEEDED(hr))
			printf("ready state: %d\n", status);

		hr = IXMLHttpRequest_get_status(xhr, &status);
		if (SUCCEEDED(hr))
			printf("http status code: %d\n", status);

		hr = IXMLHTTPRequest_get_responseXML(xhr, &disp);
		if (SUCCEEDED(hr))
		{
			printf("get_responseXML() succeeded\n");
			hr = IDispatch_QueryInterface(disp, &IID_IXMLDOMDocument, &xmldoc);
			if (SUCCEEDED(hr))
			{
				printf("IDispatch_QueryInterface() succeeded\n");
				display_xmlstr(xmldoc);
				display_xml(xmldoc);
				IXMLDOMDocument_Release(xmldoc);
			}
			else
				printf("IDispatch_QueryInterface() failed\n");
			IDispatch_Release(disp);
		}
		else
			printf("get_responseXML() failed");

		IXMLHttpRequest_Release(xhr);
	}
	printf("\n");
}

int main()
{
	CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); // 初始化COM组件对象模型

	str_test("http://adv.purasbar.com/mcu/test/str_test.php");
	str_test("http://adv.purasbar.com/mcu/test/json_test.php");

	xml_test("http://adv.purasbar.com/mcu/test/xml_test.php?txt=xp%E7%B3%BB%E7%BB%9F%E4%B8%8B%E8%BD%BD&yaya=%E5%96%9D%E5%AE%8C%E8%8D%AF%E6%84%9F%E8%A7%89%E6%B8%85%E7%88%BD%E4%BA%86%E8%AE%B8%E5%A4%9A", NULL); // get方式
	xml_test("http://adv.purasbar.com/mcu/test/xml_test.php?txt=xp%E7%B3%BB%E7%BB%9F%E4%B8%8B%E8%BD%BD", "hello=%E6%B5%8B%E8%AF%95%E7%8E%AF%E5%A2%83%E5%90%8E%E5%8F%B0%E7%AE%A1%E7%90%86%E7%B3%BB%E7%BB%9F&yaya=%E9%9B%BE%E9%9B%A8%20%E8%BF%9E%E9%98%B4%E5%A4%A9%20%E7%BE%BD%E7%BE%BD%20%E6%B5%85%E6%B5%85%E5%81%A5%E5%81%A5%E5%BA%B7%E5%BA%B7%20%E9%BB%9B%E8%A1%8D%20%E9%9F%B3%E9%9F%B3%E9%94%A6%E9%B2%A4%E9%99%84"); // post方式

	CoUninitialize();
	return 0;
}

get参数的提交方法:
将参数直接附加到URL网址的后面。如http://XXX//xml_test.php?A=B&C=D&E=F。汉字和符号必须用urlencode函数编码成%XX的形式。
post数据的提交方法:
通过VARIANT弱类型变量传入IXMLHttpRequest_send函数的第二个参数。没有post数据时要传入VT_NULL值。
汉字和符号同样也必须用urlencode函数编码成%XX的形式。只是最前面不需要以问号开头。

关于urlencode/urldecode、htmlspecialchars、trim和str_replace函数的C语言实现,请参考这篇文章:

https://blog.csdn.net/ZLK1214/article/details/131748124icon-default.png?t=N7T8https://blog.csdn.net/ZLK1214/article/details/131748124

程序运行结果:

open() succeeded
send() succeeded
ready state: 4
http status code: 200
response: 当前时间为2024年1月24日 20:37:39。

open() succeeded
send() succeeded
ready state: 4
http status code: 200
response: {"date":"2024-1-24 20:37:40","time":1706099860,"desc":"abcd\u7b80\u4f5
3\u4e2d\u6587"}

method: GET
open() succeeded
send() succeeded
ready state: 4
http status code: 200
get_responseXML() succeeded
IDispatch_QueryInterface() succeeded
xmlstr: <?xml version="1.0"?>
<test timestr="20240124203740" example="简体中文"><param method="get" name="txt"
>xp系统下载</param><param method="get" name="yaya">喝完药感觉清爽了许多</param><
/test>
timestr: 20240124203740
example: 简体中文
title: (null)
txt: xp系统下载

method: POST
open() succeeded
send() succeeded
ready state: 4
http status code: 200
get_responseXML() succeeded
IDispatch_QueryInterface() succeeded
xmlstr: <?xml version="1.0"?>
<test timestr="20240124203740" example="简体中文"><cookie name="PHPSESSID">ktvth
t5ebhkssu0k5srknmpic3</cookie><param method="get" name="txt">xp系统下载</param><
param method="post" name="hello">测试环境后台管理系统</param><param method="post
" name="yaya">雾雨 连阴天 羽羽 浅浅健健康康 黛衍 音音锦鲤附</param></test>
timestr: 20240124203740
example: 简体中文
title: (null)
txt: xp系统下载
hello: 测试环境后台管理系统

请按任意键继续. . .

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【量化交易】股市舞者:小明的撮合交易之旅

马西森AES撮合交易系统 在繁华的都市中&#xff0c;小明&#xff0c;一个普通的青年&#xff0c;刚刚赚到了人生的第一桶金——20万。这笔意外的财富&#xff0c;点燃了他对股市的强烈兴趣。他开始如饥似渴地学习金融知识&#xff0c;钻研各种交易策略。 一天&#xff0c;小…

现货黄金做日内交易和波段交易有何差异?

在现货黄金投资中&#xff0c;日内交易和波段交易都是投资者常用的手段。但投资者其实搞不懂两者有何区别&#xff0c;有时甚至不清楚自己做的是日内交易还是波段交易&#xff0c;下面我们就来讨论一下这两种交易方法的异同。 两者的区别主要是在持仓的时间上。日内交易顾名思义…

Python算法题集_接雨水

本文为Python算法题集之一的代码示例 题目42&#xff1a;接雨水 说明&#xff1a;给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,…

【计算机网络】【练习题】【新加坡南洋理工大学】【Computer Control Network】

说明&#xff1a; 仅供学习使用。 一、题目描述 该题目描述一个网络中传播时延&#xff08;Transmission Delay&#xff09;的例子。题目如下&#xff1a; 二、问题解答&#xff08;个人&#xff09; 笔者第3问采用均值不等式求解。标答中采用求导数的方法求极值。似乎均值…

el-table 动态渲染多级表头;一级表头根据数据动态生成,二级表头固定

一、表格需求&#xff1a; 实现一个动态表头&#xff0c;一级表头&#xff0c;根据数据动态生成&#xff0c;二级表头固定&#xff0c;每列的数据不一样&#xff0c;难点在于数据的处理。做这种表头需要两组数据&#xff0c;一组数据是实现表头的&#xff0c;另一组数据是内容…

WinSCP如何使用公网TCP地址访问本地服务器

文章目录 1. 简介2. 软件下载安装&#xff1a;3. SSH链接服务器4. WinSCP使用公网TCP地址链接本地服务器5. WinSCP使用固定公网TCP地址访问服务器 1. 简介 ​ Winscp是一个支持SSH(Secure SHell)的可视化SCP(Secure Copy)文件传输软件&#xff0c;它的主要功能是在本地与远程计…

文件名翻译工具,文件名称翻译软件

无论是工作、学习还是生活&#xff0c;我们时常会遇到文件名称难以理解的情况。这时&#xff0c;一款优秀的文件名称翻译软件就显得尤为重要。今天&#xff0c;我要为大家介绍一个备受好评软件——文件批量改名高手&#xff0c;这款软件自带翻译功能&#xff0c;可以帮你轻松实…

分布式锁实现(mysql,以及redis)以及分布式的概念(续)redsync包使用

道生一&#xff0c;一生二&#xff0c;二生三&#xff0c;三生万物 这张尽量结合上一章进行使用&#xff1a;上一章 这章主要是讲如何通过redis实现分布式锁的 redis实现 这里我用redis去实现&#xff1a; 技术&#xff1a;golang&#xff0c;redis&#xff0c;数据结构 …

2024 年 10 款顶级的数据恢复软件榜单

2024年&#xff0c;随着人工智能、云计算等技术的不断发展&#xff0c;数据已经成为我们生活中不可或缺的一部分。然而&#xff0c;数据丢失的风险仍然存在。删除文件、病毒攻击、硬件损坏和其他情况都可能导致数据丢失。而数据恢复软件就成为解决这一问题的有效方案。 2024 年…

springCloud的ribbon和feign

ribbon方式调用 就是将原来的具体地址&#xff0c;改为了通过服务名去调用。注册中心中有多个服务&#xff0c;相同服务名&#xff0c;就会算作可以调用的服务。 首先得有一个注册中心&#xff0c;然后各种服务注册进去&#xff0c;然后利用ribbon或者feign去调用。 ribbon是直…

微认证 openEuler社区开源贡献实践

文章目录 1. 开源与开源社区2. openEuler 社区概述3.参与openEuler社区贡献4.openEuler软件包开发Linux软件管理——源码编译 1. 开源与开源社区 Richard Matthew Stallman&#xff0c;1983年9月推出GNU项目&#xff0c;并发起自由软件运动(free software movement或free/open…

多维时序 | Matlab实现RIME-TCN-Multihead-Attention霜冰算法优化时间卷积网络结合多头注意力机制多变量时间序列预测

多维时序 | Matlab实现RIME-TCN-Multihead-Attention霜冰算法优化时间卷积网络结合多头注意力机制多变量时间序列预测 目录 多维时序 | Matlab实现RIME-TCN-Multihead-Attention霜冰算法优化时间卷积网络结合多头注意力机制多变量时间序列预测效果一览基本介绍程序设计参考资料…

Dify学习笔记-应用发布(四)

1、发布为公开 Web 站点 使用 Dify 创建 AI 应用的一个好处在于&#xff0c;你可以在几分钟内就发布一个可供用户使用的 Web 应用&#xff0c;该应用将根据你的 Prompt 编排工作。 如果你使用的是自部署的开源版&#xff0c;该应用将运行在你的服务器上 如果你使用的是云服务&…

3.确认弹窗(ConfirmPopup)

愿你出走半生,归来仍是少年&#xff01; 环境&#xff1a;.NET 7 在开发中&#xff0c;最常用的弹窗之一表示确认弹窗&#xff0c;为了减少重复的开发工作&#xff0c;所以需要基于Popup进行封装。 1.布局 分为标题、确认内容、按钮三个区域&#xff0c;都是可供调整的。 &l…

java复习篇 数据结构:链表第二节 哨兵

目录 单向链表哨兵 初始 头插 思路 代码 尾插 思路 遍历 遍历验证头插 尾插代码 尾插测试 get 思路 代码 测试 insert 思路 代码 测试 remove 移除头结点 提问 移除指定位置 测试 单向链表哨兵 单向链表里面有一个特殊的节点称为哨兵节点&#xff0c;…

MacOS 无法ping 通 github.com 解决方案

ping github.com 会显示请求超时&#xff1a; PING github.com (192.30.253.112): 56 data bytes Request timeout for icmp_seq 0 Request timeout for icmp_seq 1 Request timeout for icmp_seq 2 Request timeout for icmp_seq 3 Request timeout for icmp_seq 4 Request …

一文了解Ceph原理以及常见ceph指令

一、Ceph介绍 什么是分布式存储&#xff1f; 与集中式存储相反&#xff0c;分布式存储通常采用存储单元集群的形式。并且具有在集群节点之间进行数据同步和协调的机制。其目的是为了通过服务器解决大规模&#xff0c;高并发情况下的Web访问问题。 Ceph是一个统一的、分布式的存…

如何利用H5页面引导关注公众号-数灵通

随着流量获取成本的增加&#xff0c;许多企业开始寻找新的引流渠道来储存流量。H5小活动成为了一种有效的引流方式&#xff0c;并且在客户之间传递&#xff0c;形成了裂变效应。企业开始将目光转向H5网站&#xff0c;希望通过引导客户关注公众号来提升品牌影响力。 为了实现这一…

143基于matlab的2D平面桁架有限元分析

基于matlab的2D平面桁架有限元分析&#xff0c;可以改变材料参数&#xff0c;输出平面结构外形&#xff0c;各桁架应力&#xff0c;位移及作用力。可查看节点力&#xff0c;程序已调通&#xff0c;可直接运行。 143 matlab 平面桁架 有限元分析 桁架应力 (xiaohongshu.com)

温湿度传感器原理解析,温湿度传感器的应用场景有哪些?

作为常见的检测装置&#xff0c;现在已经有大大小小几十种传感器出现在我们的日常生活中。作为能够测量环境温度和湿度的传感器&#xff0c;温湿度传感器正是最常见的传感器之一&#xff0c;作为温湿度监测系统的一部分&#xff0c;被广泛应用于智慧机房、智慧楼宇、智慧农业等…