Libcurl实现HTTP/HTTPS客户端(支持get、post、保持session)

2023-05-16

前面的文章《Libcurl编译指南——Android和Windows系统》已经就libcurl在Windows和Android系统编做了详细的说明。
本文档用C/C++实现简单的HTTP/HTTPS客户端,支持get和post,支持保持session和长连接。

httpConn.h

#ifndef __HTTP_CONN_H__
#define __HTTP_CONN_H__

#include "curl.h"

#define RETRY_TIMES	3

struct MemoryStruct {
	char			*memory;
	unsigned int	size;
};

class RequestHandler
{
private:

public:
	MemoryBlock		request;
	MemoryBlock     response;
	int				http_code;
};

class HttpRequest
{
private:
	CURL				*curl_handle;
	CURLcode			curl_res;
	long				http_code;
	struct MemoryStruct receive_header;
	struct MemoryStruct receive_content;
	struct MemoryStruct error_message;
	struct curl_slist	*http_headers;

	int					retry_times;

public:
	HttpRequest();
	~HttpRequest();

	int			setRequestUrl(const char *url);	// 设置URL
	int			setRequestHeader(const char *header); // 设置Header
	int			setRequestTimeout(long time); // 设置超时时间
	int			setPostData(const char *data, unsigned int size); // 设置post数据
	int			setResultCallback(); // 回调

	int			performRequest(); // 发送数据
	int			sendReceiveEx(const char *url, RequestHandler *handler); // 发送和接收url请求

	int			getHttpCode(); //返回http code
	int			getHeader(char *header, unsigned int *len); // 返回Header
	int			getContent(char *content, unsigned int *len);
};

#endif

httpConn.cpp

#include "httpConn.h"
#include "curl.h"

static unsigned int RetriveContentCallback(void *contents, unsigned int size, unsigned int nmemb, void *userp)
{
	unsigned int realsize = size * nmemb;
	struct MemoryStruct *mem = (struct MemoryStruct *)userp;

	char *ptr = (char*)realloc((void *)mem->memory, mem->size + realsize + 1);
	if (ptr == NULL) {
		/* out of memory! */
		printf("not enough memory (realloc returned NULL)\n");
		return -6;
	}

	mem->memory = ptr;
	memcpy(&(mem->memory[mem->size]), contents, realsize);
	mem->size += realsize;
	mem->memory[mem->size] = 0;

	return realsize;
}

static unsigned int RetriveHeaderCallback(void *contents, unsigned int size, unsigned int nmemb, void *userp)
{
	unsigned int realsize = size * nmemb;
	struct MemoryStruct *mem = (struct MemoryStruct *)userp;

	char *ptr = (char*)realloc((void *)mem->memory, mem->size + realsize + 1);
	if (ptr == NULL) {
		/* out of memory! */
		printf("not enough memory (realloc returned NULL)\n");
		return -6;
	}

	mem->memory = ptr;
	memcpy(&(mem->memory[mem->size]), contents, realsize);
	mem->size += realsize;
	mem->memory[mem->size] = 0;

	return realsize;
}

HttpRequest::HttpRequest()
{
	curl_res = CURLE_OK;
	http_code = 0;
	curl_handle = NULL;
	http_headers = NULL;
	retry_times = RETRY_TIMES;

	/* will be grown as needed by the realloc above */
	receive_content.memory = (char*)malloc(1); 
	receive_header.memory = (char*)malloc(1);
	error_message.memory = (char*)malloc(1);

	/* no data at this point */
	receive_content.size = 0;  
	receive_header.size = 0;

	/* global libcurl initialisation */
	curl_global_init(CURL_GLOBAL_ALL);

	/* init the curl session */
	curl_handle = curl_easy_init();
}

HttpRequest::~HttpRequest()
{
	/* cleanup curl stuff */
	if (curl_handle)
	{
		curl_easy_cleanup(curl_handle);
	}

	free(receive_content.memory);
	free(receive_header.memory);
	free(error_message.memory);

	if (http_headers)
	{
		curl_slist_free_all(http_headers);
	}
	
	/* we're done with libcurl, so clean it up */
	curl_global_cleanup();
}

int HttpRequest::setRequestUrl(const char *url)
{
	if (0 == memcmp(url, "https", 5))
	{
		curl_res = curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_SSL_VERIFYPEER failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		curl_res = curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_SSL_VERIFYHOST failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}
	}

#ifdef USE_PROXY
	curl_res = curl_easy_setopt(curl_handle, CURLOPT_PROXY, PROXY_ADDRESS);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_PROXY failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}
#endif // USE_PROXY

	curl_res = curl_easy_setopt(curl_handle, CURLOPT_URL, url);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_URL failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}

	return 0;
}

int HttpRequest::setRequestHeader(const char * header)
{
	http_headers = curl_slist_append(http_headers, header);
	curl_res = http_headers ? CURLE_OK : CURLE_FAILED_INIT;
	if (CURLE_OK != curl_res)
	{
		printf("Set request header: curl_slist_append failed.");
		return -2;
	}

	return 0;
}

int HttpRequest::setRequestTimeout(long time)
{
	curl_res = curl_easy_setopt(curl_handle, CURLOPT_TIMEOUT, time);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_TIMEOUT failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}

	return 0;
}

int HttpRequest::setPostData(const char *data, unsigned int size)
{
	curl_res = curl_easy_setopt(curl_handle, CURLOPT_POST, 1);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_POST failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}

	curl_res = curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, data);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_POSTFIELDS failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}

	curl_res = curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDSIZE, size);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_POSTFIELDSIZE failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}

	return 0;
}

int HttpRequest::setResultCallback()
{
	/* send all data to this function  */
	curl_res = curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, RetriveContentCallback);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_WRITEFUNCTION failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}

	/* we pass our 'receive_content' struct to the callback function */
	curl_res = curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&receive_content);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_WRITEDATA failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}

	/*curl_res = curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, RetriveHeaderCallback);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_HEADERFUNCTION failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}

	curl_res = curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, (void *)&receive_header);
	if (CURLE_OK != curl_res)
	{
		printf("curl_easy_setopt CURLOPT_HEADERDATA failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
		return -1;
	}*/

	return 0;
}

int HttpRequest::performRequest()
{
	if (curl_handle)
	{
		setResultCallback();
		setRequestTimeout(10);

		if (http_headers)
		{
			curl_res = curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, http_headers);
			if (CURLE_OK != curl_res)
			{
				printf("curl_easy_setopt CURLOPT_HTTPHEADER failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
				return -1;
			}
		}

		/* some servers don't like requests that are made without a user-agent field, so we provide one */
		curl_res = curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_USERAGENT failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		curl_res = curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_NOPROGRESS failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		curl_res = curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_NOSIGNAL failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		curl_res = curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT_MS, 0);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_CONNECTTIMEOUT_MS failed. curl_res = %d,  curl_strerror = %s", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		/* get it! */
		curl_res = curl_easy_perform(curl_handle);
		if (curl_res == CURLE_OPERATION_TIMEDOUT)
		{
			int retry_count = retry_times;
			while (retry_count > 0)
			{
				curl_res = curl_easy_perform(curl_handle);
				if (curl_res != CURLE_OPERATION_TIMEDOUT) break;
				retry_count--;
			}
		}

		if (curl_res == CURLE_OPERATION_TIMEDOUT)
		{
			printf("curl_easy_perform failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -3;
		}

		curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &http_code);
		if (curl_res != CURLE_OK || http_code != 200)
		{
			printf("curl_easy_perform failed. curl_res = %d, Httpcode = %ld, curl_strerror = %s\n", curl_res, http_code, curl_easy_strerror(curl_res));
			return -4;
		}

		/*
		 * Now, our receive_content.memory points to a memory block that is receive_content.size
		 * bytes big and contains the remote file.
		 *
		 * Do something nice with it!
		 */
	}

	return 0;
}

int HttpRequest::sendReceiveEx(const char * url, RequestHandler * handler)
{
	int ret = 0;
	int httpCpde = 0;
	char receive[20480] = { 0 };
	unsigned int rlen = sizeof(receive);
	char requet[10240] = { 0 };

	if (0 != handler->request.getSize())
	{
		sprintf(requet, "%s?%s#", url, handler->request.getData());
	}
	else
	{
		sprintf(requet, "%s", url);
	}


	if (receive_content.memory)
	{
		free(receive_content.memory);
		receive_content.memory = NULL;
		receive_content.memory = (char*)malloc(1);
		receive_content.size = 0;
	}

	if (curl_handle)
	{
		// set params 
		curl_easy_reset(curl_handle);

		/* enable TCP keep-alive for this transfer */
		curl_easy_setopt(curl_handle, CURLOPT_TCP_KEEPALIVE, 1L);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_TCP_KEEPALIVE failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		/* keep-alive idle time to 120 seconds */
		curl_easy_setopt(curl_handle, CURLOPT_TCP_KEEPIDLE, 120L);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_TCP_KEEPIDLE failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		/* interval time between keep-alive probes: 30 seconds */
		curl_easy_setopt(curl_handle, CURLOPT_TCP_KEEPINTVL, 30L);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_TCP_KEEPINTVL failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		/* export cookies to this file when closing the handle */
		curl_easy_setopt(curl_handle, CURLOPT_COOKIEJAR, "./cookies.txt");
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_COOKIEJAR failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		/* get cookies from an existing file */
		curl_easy_setopt(curl_handle, CURLOPT_COOKIEFILE, "./cookies.txt");
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_COOKIEFILE failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		setResultCallback();
		setRequestTimeout(10);

		ret = setRequestUrl(url);
		if (0 != ret)
		{
			return ret;
		}

		setPostData((const char *)handler->request.getData(), handler->request.getSize());

		if (http_headers)
		{
			curl_res = curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, http_headers);
			if (CURLE_OK != curl_res)
			{
				printf("curl_easy_setopt CURLOPT_HTTPHEADER failed. curl_res = %d,  curl_strerror = %s", curl_res, curl_easy_strerror(curl_res));
				return -1;
			}
		}

		curl_res = curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_NOPROGRESS failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		curl_res = curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_NOSIGNAL failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		curl_res = curl_easy_setopt(curl_handle, CURLOPT_CONNECTTIMEOUT_MS, 0);
		if (CURLE_OK != curl_res)
		{
			printf("curl_easy_setopt CURLOPT_CONNECTTIMEOUT_MS failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			return -1;
		}

		/* get it! */
		curl_res = curl_easy_perform(curl_handle);
		if (curl_res == CURLE_OPERATION_TIMEDOUT)
		{
			int retry_count = retry_times;
			while (retry_count > 0)
			{
				curl_res = curl_easy_perform(curl_handle);
				if (curl_res != CURLE_OPERATION_TIMEDOUT) break;
				retry_count--;
			}
		}

		if (curl_res == CURLE_OPERATION_TIMEDOUT)
		{
			printf("curl_easy_perform failed. curl_res = %d,  curl_strerror = %s\n", curl_res, curl_easy_strerror(curl_res));
			ret = -3;
		}

		http_code = 0;
		curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &http_code);
		if (curl_res == CURLE_OK && http_code == 200)
		{
			/*
			 * Now, our receive_content.memory points to a memory block that is receive_content.size
			 * bytes big and contains the remote file.
			 *
			 * Do something nice with it!
			 */

			getContent(receive, &rlen);
			char *response = (char*)handler->response.resize(rlen, rlen + 4, false);
			memset(response, '\0', rlen+4);
			memcpy(response, receive, rlen);
			response[rlen] = '\0';

			httpCpde = getHttpCode();
			handler->http_code = httpCpde;

			printf("sendReceive() <<< Data : \n%s\n[response data len : %d]\n", handler->response.getData(), handler->response.getSize());

			ret = 0;
		}
		else
		{
			printf("curl_easy_perform failed. curl_res = %d, Httpcode = %ld, curl_strerror = %s\n", curl_res, http_code, curl_easy_strerror(curl_res));
			return -4;
		}
	}

	return ret;
}

int HttpRequest::getHttpCode()
{
	return http_code;
}

int HttpRequest::getHeader(char *header, unsigned int *len)
{
	if (receive_header.size > *len)
	{
		return -5;
	}

	memcpy(header, receive_header.memory, receive_header.size);
	*len = receive_header.size;

	return 0;
}

int HttpRequest::getContent(char *content, unsigned int *len)
{
	if (receive_content.size > *len)
	{
		return -5;
	}

	memcpy(content, receive_content.memory, receive_content.size);
	*len = receive_content.size;

	return 0;
}

Demo

#include <stdio.h>
#include "httpConn.h"

// 封装自己的客户端
int customizeSendReceive(const char *url)
{
	int			ret = 0;
	HttpRequest req;

	int httpCpde = 0;
	char receive[204800] = { 0 };
	unsigned int rlen = sizeof(receive);

	do
	{
		int urlLen = strlen(url);
		if (0 >= urlLen)
		{
			break;
		}

		ret = req.setRequestUrl(url);
		if (0 != ret)
		{
			break;
		}

		ret = req.performRequest();
		if (0 != ret)
		{
			break;
		}

		httpCpde = req.getHttpCode();
		ret = req.getContent(receive, &rlen);
		if (0 != ret)
		{
			break;
		}
	} while (0);

	if (0 == ret && 200 == httpCpde)
	{
		printf("ReceivevData :");
		for (int i = 0; i < rlen; i++)
		{
			printf("%c", receive[i]);
		}
		printf("\n");
	}
	else
	{
		printf("sendReceive() failed.\n");
	}

	return ret;
}

// 使用httpClient已经实现的客户端
void testSys(const char *url, const char *post_data)
{
	HttpRequest		m_Conn;	
	RequestHandler  handler;
	
	handler.request.resize(0);
	handler.response.resize(0);
	
	int rlen = strlen(data);
	char *request = (char*)handler->request.resize(rlen, rlen + 4, false);
	memset(request, '\0', rlen+4);
	memcpy(request, post_data, rlen);
	
	int ret = m_Conn.sendReceiveEx(url, &handler);
	if (0 != ret)
	{
		printf("sendReceiveEx failed, ret = %d\n", ret);
	}
	else 
	{
		printf("response data : %s\n", (char *)handler.response.getData());
	}
}

int main(int argc, char *argv[])
{
	//customizeSendReceive("www.xxx.com?xxxxxx#");
	//testSys("www.xxx.com", "?...#");
	
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Libcurl实现HTTP/HTTPS客户端(支持get、post、保持session) 的相关文章

  • 基于esp32-cam的监控小车

    1 购买器材 xff1a Eap32 cam L289N直流步进电机驱动 自锁开关 两节18650电池 5v电源 杜邦线若干 2 程序代码 2 1 下载代码 下载库函数 百度网盘 xff1a 链接 xff1a https pan baidu
  • APP Inventor -环境安装

    APP inventor可以实现直接在网页上操作 1 登录网址 xff1a http ai2 17coding net xff08 我使用的是微软浏览器 xff0c 用谷歌打开时显示无法登录 xff09 选择一键试用 2 下载Ai伴侣 xf
  • App inventor—安安机器人

    1 准备素材 2 程序设计 3 程序编程 3 1 3 2 3 3 总结 xff1a 1 换背景图片的时候 xff0c 设置图片 gt 用文本来存放图片的名称 xff08 特别注意后面的png xff0c 是图片的格式 xff09 2 手机震
  • 按键控制LED灯亮灭——基于arduino单片机

    程序设计 xff1a 函数 xff1a digitalRead 作用 xff1a 用来读取数字串口状态 xff0c HIGH还是LOW xff08 其实还有一种表达方式就是HIGH是 1 LOW是 0 xff0c 只是HIGH LOW更直观
  • JDY-31 蓝牙模块使用(HC-06)

    波特率要相同才能就行通讯 下载串口调试工具 打开串口调试工具 xff0c 配置参数 蓝牙连接 VCC 3 3V GND GND TXD RXD RXD TXD 配置蓝牙参数 发送指令 xff0c 要在指令后面添加 r n xff0c 或者让
  • arduino驱动LD3320语音识别模块

    LD3320 xff1a LD3320 是一颗基于非特定人语音识别 xff08 SI ASR xff1a Speaker Independent Automatic SpeechRecognition xff09 技术的语音识别 声控芯片
  • 无人机学习笔记之电池篇

    电池参数 电池的多少mAh 表示电池容量 xff0c 如1000mah电池 xff0c 如果以1000ma放电 xff0c 可持续放电1小时 如果以500mA放电 xff0c 可以持续放电2小时电池后面多少C 代表电池放电能力 这是普通锂电
  • 指纹锁—AS608指纹模块

    目录 一 工程内容 二 AS608指纹模块使用 1 AS608 与 USB转TTL模块 的接线 2 上位机配置 3 AS608与STC12C60A通讯 三 驱动MG995 xff08 180度舵机 xff09 1 MG995舵机数据手册 2
  • 手把手使用Python语音识别,进行语音转文字

    目录 0 太长不看系列 xff0c 直接使用 识别结果 1 Python调用标贝科技语音识别接口 xff0c 实现语音转文字 1 1 环境准备 xff1a 1 2 获取权限 1 2 1 登录 1 2 2 创建新应用 1 2 3 选择服务 1
  • python编译问题—Traceback (most recent call last): File “E:\python\pythonProject\文件读取.py“, line 3, in <

    Traceback most recent call last File 34 E python pythonProject 文件读取 py 34 line 3 in lt module gt f 61 open r 39 D 测试 tex
  • Python爬虫——爬取搜狗页面

    直接上代码 xff01 xff01 xff01 usr bin env python coding utf 8 8 需求 xff1a 爬取搜狗首页的页面数据 import requests if name 61 61 34 main 34
  • 数据结构-删除排序数组中的重复项

    class Solution public int removeDuplicates vector lt int gt amp nums int n lenght lenght 61 nums size 获取数组长度 if lenght 6
  • linux学习-虚拟机下载

    虚拟机下载 xff1a https www vmware com cn products workstation pro html 安装完成后 检测网络适配卡 xff1a 选择系统下载 OK
  • 硬件MSB最高位优先、LSB最低位优先的CRC计算原理详细解释和程序,正算反算成功等效,DS18B20和HTU31D传感器CRC

    wxleasyland 64 139 com 2022 7 以前写过 我学习CRC32 CRC16 CRC原理和算法的总结 xff08 与WINRAR结果一致 xff09 长篇 经过十几年又忘记了 这次碰到DS18B20进行CRC校验 xf
  • android4.4上sd卡的读写权限

    Google去年11月正式发布了Android 4 4 xff0c 代号为KitKat xff08 奇巧 xff0c 雀巢的一款巧克力品牌 xff09 xff0c 该系统带来了诸多新的特性 但需要注意的是 xff0c 该系统可能会让你之前一
  • android时间控件

    原文地址 xff1a http www 360doc com content 14 0617 16 18203124 387517665 shtml 前言 这一篇博客分别讲解Android平台下 xff0c 关于日期和时间的几个相关控件 包
  • Android开发-API指南-<application>[原创译文]

    转载地址 xff1a http blog sina com cn s blog 48d491300100zmga html lt application gt 英文原文 xff1a http developer android com gu
  • 新入职项目经理务必避免的七个常见错误

    在国内 xff0c 好多项目经理都是技术专家出身 xff0c 所以标题给了 34 新入职 34 由于旧习惯 xff0c 身上可能存在众多需要改进的地方 一 不明确自身的职责 你不在是个码农 xff1f 公司聘请你不是为了让你去写代码 xff
  • How Android Handles Touches

    Touch System overview Touch Event Framework Custom Touch Handling System Provided Touch Handlers System Provided Gesture
  • MFCC特征介绍

    MFCC特征介绍 在语音识别技术中 xff0c 需要提取音频的特征 xff0c 然后就可以使用该音频进行模型的训练或者是进行识别 xff0c 目前很常用的一种特征叫做MFCC特征 xff0c 又叫做梅尔倒谱系数特征 MFCC特征保留了语义相

随机推荐

  • 字符串大小比较问题

    首先 字符串比较函数 xff1a strcmp xff08 字符串1 字符串2 xff09 xff1b 其使用规则为 xff1a 若字符串1和字符串2相等 xff0c 返回0 若字符串1大于字符串2 xff0c 返回一个正整数 43 1 若
  • OBS 录制没有声音怎么办?

    1 检查obs设置 音频 是否是默认选项 2 检查win10 是否允许使用麦克风 1 xff09 右下角出现麦克风标识 2 xff09 设置 隐私 麦克风 xff0c 查看允许放开你的麦克风是否打开 如果上述还是为解决问题 xff0c 那么
  • android.os.deadObjectException异常

    deadObjectException异常 xff0c 说明应用的service已经停止 xff0c 要么是从操作系统中丧生 xff0c 要么从应用程序中终止
  • 2038问题

    2038年一月19号 xff0c 星期二 xff0c 凌晨3点14分7秒钟的时候 xff0c 如果Linux程序员会做恶梦的话 xff0c 那么梦的内容一定是关于这个日期的 xff0c 在这一秒钟滑过后 xff0c 凡是安装着linux的计
  • ChkBugReport工具for Android

    关于这个工具 xff0c 找到的资料都比较旧了 xff0c 貌似是索尼移动的开发人员开发的 xff0c 2014年左右的文章比较多 xff0c 应该是那个时候索尼移动还是比较鼎盛的时期吧 现在已经很少看到关于这个工具的文章了 xff0c G
  • kernel panic

    Linux kernel panic是很难定位和排查的重大故障 一旦系统发生了kernel panic xff0c 相关的日志信息非常少 xff0c 而一种常见的排查方法 重现法 又很难实现 xff0c 因此遇到kernel panic的问
  • PS域业务与CS域业务的区别

    1 CS和PS是针对核心网部分而言的 xff0c 两者的不同在于交换方式 CS是电路交换 xff0c 通信之前 xff0c 资源预留 xff0c 不同用户独占各自分配的资源 xff0c 没有统计复用 PS是包交换 xff0c 不同的用户可以
  • sh_脚本语法

    介绍 xff1a 1 开头 程序必须以下面的行开始 xff08 必须方在文件的第一行 xff09 xff1a bin sh 符号 用来告诉系统它后面的参数是用来执行该文件的程序 在这个例子中我们使用 bin sh来执行程序 当编写脚本完成时
  • 【深度学习系列(三)】:基于CNN+seq2seq公式识别系统实现 (1)

    这段时间一直在做公式识别相关的项目 xff0c 尝试了传统的方法 xff0c 效果不怎么好 想到能不能使用深度学习的方法进行相关方法 然后在github找到了相关代码 xff0c 这里做下分析 具体github地址 xff1a GitHub
  • 困惑多年,为什么printf可以重定向?

    很多人在用printf函数进行串口打印的时候 xff0c 都会被告知需要重定向fputc函数 xff08 别的平台可能不是这个函数 xff09 xff0c 让字符串数据输出到指定串口 xff0c 按照网上的教程也能很快解决 但是却没人告诉你
  • 多线程并发编程

    文章目录 多线程并发编程一 多线程带来的问题相关概念 二 互斥1 互斥与互斥量2 申请互斥量I 静态方法申请互斥量 xff1a II 动态方法申请互斥量 xff1a 3 利用互斥量加锁与解锁4 销毁互斥量5 互斥量综合应用 模拟抢票6 互斥
  • 【嵌入式】---- 串口UART波形分析

    串口参数的配置 波特率 xff08 bit s xff09 xff1a 大多数使用115200 但有些芯片特殊 xff0c 具体要看数据手册中波特率的容错率 比如中微的CMS32L051就不支持115200bps 停止位 xff1a 一般选
  • 手把手教你用JAVA实现“语音合成”功能(文字转声音)标贝科技

    手把手教你用JAVA实现 语音合成 功能 xff08 文字转声音 xff09 标贝科技 前言 什么是语音合成 xff1f 将文本转换成自然流畅的语音 xff0c 本篇文章将介绍 实时在线合成 xff08 文本长度不得超过1024字节 xff
  • cv::imread(cv::String const&, int)’未定义的引用

    在 Makefile文件的195 行 LIBRARIES 43 61 opencv core opencv highgui opencv imgproc 后面添加 xff1a opencv imgcodecs opencv videoio修
  • 【C/C++】C++ 网络多线程编程

    关键词 xff1a C C 43 43 网络编程 多线程 套接字 UDP 前言 学习C 43 43 网络编程多线程编程的目的 xff1a 巩固C 43 43 xff1b 由于C 43 43 大多用于服务器 xff0c 因此网络和多线程是进入
  • 在ubuntu20.04上配置VINS_Fusion(亲测有效,一应俱全)

    最近在做科研训练的时候配置了HKUST Aerial Robotics实验室的VINS Fusion代码项目 xff0c 经历了一些编译报错的问题 xff0c 在网上查找的时候博客内容良莠不齐 xff0c 且实质针对性意见不多 xff0c
  • 无人机项目跟踪记录二十五--无线接收模块的输入输出

    无线接收模块的功能是接收无线遥控器的命令 xff08 应该对应的是无人机上面的无线接收芯片 xff09 xff0c 无人机根据接收的指令进行不同的处理 用同样方法 xff0c 无线接收模块包含的函数是 xff1a Nrf Irq void
  • UDP校验和及代码

    UDP校验和采用反码求和 xff1a 两数相加 xff0c 把超出16位加入到第0位 校验和算法 unsigned short UDPCheck unsigned short data int len int carryBit 61 0 i
  • ROS Moveit:rviz和gazebo仿真出现rviz规划后gazebo没有反应

    在用rviz规划后 xff0c 警告 WARN 1649654675 728414350 42 937000000 Failed to validate trajectory couldn 39 t receive full current
  • Libcurl实现HTTP/HTTPS客户端(支持get、post、保持session)

    前面的文章 Libcurl编译指南 Android和Windows系统 已经就libcurl在Windows和Android系统编做了详细的说明 本文档用C C 43 43 实现简单的HTTP HTTPS客户端 xff0c 支持get和po