当前位置: 首页 > news >正文

树莓派开发笔记10-树莓派的HTTP通信实验

github主页:https://github.com/snqx-lqh
gitee主页:https://gitee.com/snqx-lqh
本项目github地址:https://github.com/snqx-lqh/RaspberryPiLearningNotes
本项目gitee地址:https://gitee.com/snqx-lqh/RaspberryPiLearningNotes
欢迎交流

HTTP通信

我这篇文章将会使用c语言下的curl库在树莓派3B+上实现http的get和post,python语言下使用requests来实现get和post。

文中部分内容参考

https://openatomworkshop.csdn.net/6629c2a71a836825ed7b8370.html

C语言实现

安装curl相关的库

sudo apt-get install libcurl4-openssl-dev
sudo apt-get install curl

关于测试,我是用的yapi创建的两个请求处理,可以去那个网站查看相关的处理,官网,我使用的不是很好,所以我暂时也不写教程了,可以用我下面的代码链接做测试。短时间应该不会改动。

Curl处理相关库

一般处理流程是

初始化CURL库->获取CURL句柄用于本次传输->设置的传输配置选项->执行请求->处理响应->清理->全局清理

1、初始化Curl库,这个函数只能用一次。(调用curl_global_cleanup清理后可再次使用初始化)

CURLcode curl_global_init(long flags);
  • flags
    CURL_GLOBAL_ALL: 初始化所有的 libcurl 功能。
    CURL_GLOBAL_SSL: 初始化 SSL 相关的功能,如支持 HTTPS 议。
    CURL_GLOBAL_WIN32: 在 Windows 平台上初始化一些特定的功能。
    CURL_GLOBAL_NOTHING: 不做任何初始化,这种情况下需要手动初始化特定的功能。
  • 返回值: CURLcode 类型的错误码,如果初始化成功则返回 CURLE_OK,否则返回其他错误码表示初始化失败

2、获取Curl句柄用于本次传输,每次传输都需要有一个句柄初始化

CURL *curl = curl_easy_init();

3、设置的传输配置选项,设置多种配置,请求头、URL啥的

curl_easy_setopt(handle, option, value)

例如

struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);	//设置请求头
curl_easy_setopt(curl, CURLOPT_URL, "http://example.com");	//设置 URL
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "key1=value1&key2=value2");	//设置请求体
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L); // 设置请求超时时间,超时时间为10秒
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);//设置写数据回调函数

4、执行请求,执行一次HTTP请求

CURLcode res = curl_easy_perform(curl); 

5、处理响应

if (res != CURLE_OK) {fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
} else {    // 请求成功,处理响应数据  }

以下是常见的错误代码

CURLE_OK (0): 操作成功完成。
CURLE_UNSUPPORTED_PROTOCOL (1): 不支持的协议。
CURLE_URL_MALFORMAT (3): URL 格式错误。
CURLE_COULDNT_RESOLVE_HOST (6): 无法解析主机名。
CURLE_COULDNT_CONNECT (7): 无法连接到主机或代理。
CURLE_OPERATION_TIMEDOUT (28): 操作超时。
CURLE_GOT_NOTHING (52): 未收到任何数据。
CURLE_SEND_ERROR (55): 发送数据时出错。
CURLE_RECV_ERROR (56): 接收数据时出错。

6、清理: 执行完HTTP请求后,需要清理资源,包括清理CURL句柄和释放libcurl相关的资源。curl_easy_cleanup(curl);

7、全局清理: 在程序结束前,需要对libcurl进行全局清理,释放相关资源。curl_global_cleanup();

Get请求

知道了上面的流程,我们写一个GET的处理实例,处理实验代码如下

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <curl/curl.h>  //用于处理接收到的数据的回调函数
size_t GetDataWriteCallback(void *ptr, size_t size, size_t nmemb, FILE *stream)
{//将读到的数据放进标准输出打印出来//fwrite(ptr, size, nmemb, stdout); char *str = (char*)ptr; printf("%s\n",str);return size * nmemb; // 返回写入的字节数 
}int GetUrlData(const char *url)
{CURL *curl;  CURLcode res;  curl = curl_easy_init();if(curl){// 设置要访问的URL  curl_easy_setopt(curl, CURLOPT_URL, url);  // 禁用将HTTP头输出到标准输出(如果你需要的话,可以开启这个选项)  curl_easy_setopt(curl, CURLOPT_HEADER, 0L);  // 设置数据接收的回调函数  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, GetDataWriteCallback);  // 执行CURL会话  res = curl_easy_perform(curl);  // 检查是否有错误发生  if (res != CURLE_OK) {  fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));  return 1;  }      // 清理  curl_easy_cleanup(curl);  return 0; }return 1;
}int main(int argc,char **argv)
{curl_global_init(CURL_GLOBAL_ALL);const char *GetUrl = "https://yapi.pro/mock/194105/emp/list"; if (!GetUrlData(GetUrl)) {  printf("Data fetched successfully.\n");  } else {  printf("Failed to fetch data.\n");  } curl_global_cleanup(); return 0; 
}

然后编译这段代码

gcc -Wall main.c -o main  

-Wall 表示编译时显示所有警告

编译完成后调用生成的main文件

sudo ./main

想要停止这个程序,Ctrl+c即可。

Post请求

知道了上面的流程,我们写一个POST的处理实例,处理实验代码如下

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <curl/curl.h>  size_t PostDataWriteCallback(void *ptr, size_t size, size_t nmemb, FILE *stream)
{//将读到的数据放进标准输出打印出来//fwrite(ptr, size, nmemb, stdout); char *str = (char*)ptr; printf("%s\n",str);return size * nmemb; // 返回写入的字节数 
}int PostUrlData(const char *url, const char *json_data)
{CURL *curl;  CURLcode res;  curl = curl_easy_init();  if (curl) {  // 设置要访问的URL  curl_easy_setopt(curl, CURLOPT_URL, url);  // 设置POST请求  curl_easy_setopt(curl, CURLOPT_POST, 1L);  // 设置POST数据  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json_data);  // 设置Content-Type头  struct curl_slist *headers = NULL;  headers = curl_slist_append(headers, "Content-Type: application/json");  curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);  // 设置数据接收的回调函数(对于POST请求,这通常不是必需的)  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, PostDataWriteCallback);  // 执行CURL会话  res = curl_easy_perform(curl);  // 检查是否有错误发生  if (res != CURLE_OK) {  fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));  curl_slist_free_all(headers); // 释放HTTP头  curl_easy_cleanup(curl);  return 1;  }  // 释放HTTP头  curl_slist_free_all(headers);  // 清理  curl_easy_cleanup(curl);  return 0;  }  // 如果curl初始化失败  return 1;  
}int main(int argc,char **argv)
{curl_global_init(CURL_GLOBAL_ALL);const char *PostUrl = "https://yapi.pro/mock/194105/postData";const char *json_data = "{\"code\":\"13\"}"; // 示例JSON字符串if (!PostUrlData(PostUrl,json_data)) {  printf("JSON data posted successfully.\n");  } else {  printf("Failed to post JSON data.\n");  } curl_global_cleanup(); return 0; 
}

然后编译这段代码

gcc -Wall main.c -o main  

-Wall 表示编译时显示所有警告

编译完成后调用生成的main文件

sudo ./main

想要停止这个程序,Ctrl+c即可。

Python实现

这里的使用,还是使用的第6节笔记建立的虚拟环境,如果不想看那节也可以自己再建一个

我们使用python安装的时候,应该会报错error: externally-managed-environment,网上有几种方法解决,可以参考这篇博文,我使用的是他说的创建venv的方式。

python -m venv ~/myenv        #创建虚拟环境,myenv就是环境名
source ~/myenv/bin/activate   #使能我们创建的虚拟环境
pip install luma.oled         #再次Pip安装

其他env操作

deactivate #退出环境

然后使用的是requests来实现get和post

pip install requests

Get请求

import requests  url = 'https://yapi.pro/mock/194105/emp/list'  
response = requests.get(url)  
print(response.status_code)  # 打印响应状态码  
print(response.text)         # 打印响应内容(字符串形式)

Post请求

import requests url = 'https://yapi.pro/mock/194105/postData'  
data = {'code': '12'}  
response = requests.post(url, data=data)  
print(response.json())  # 如果响应是JSON格式,则可以直接解析

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——6.vector
  • 【YOLO5 项目实战】(6)YOLO5+StrongSORT 目标追踪
  • 再学C++(一):C++中类与结构体的区别
  • 【C++ Primer Plus习题】2.6
  • 模型优化之剪枝
  • libevent之android与鸿蒙编译过程
  • H3C M-LAG与双活网关接口结合应用场景实验
  • 数据结构-链表-第二天
  • elasticsearch的高亮查询三种模式查询及可能存在的问题
  • 数据结构----双向链表
  • linux笔记1
  • 删除 Docker 容器的日志文件
  • 线程通信【详解】
  • 使用DOM破坏启动xss
  • 机器学习-识别手写数字
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 5、React组件事件详解
  • Docker 笔记(2):Dockerfile
  • Hexo+码云+git快速搭建免费的静态Blog
  • jquery ajax学习笔记
  • Mysql5.6主从复制
  • zookeeper系列(七)实战分布式命名服务
  • 阿里研究院入选中国企业智库系统影响力榜
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 基于HAProxy的高性能缓存服务器nuster
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 面试题:给你个id,去拿到name,多叉树遍历
  • 爬虫模拟登陆 SegmentFault
  • 深入 Nginx 之配置篇
  • 在electron中实现跨域请求,无需更改服务器端设置
  • 自动记录MySQL慢查询快照脚本
  • ​学习一下,什么是预包装食品?​
  • (2020)Java后端开发----(面试题和笔试题)
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (LeetCode 49)Anagrams
  • (NO.00004)iOS实现打砖块游戏(十二):伸缩自如,我是如意金箍棒(上)!
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (笔试题)分解质因式
  • (分类)KNN算法- 参数调优
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (七)c52学习之旅-中断
  • (十六)串口UART
  • (转)Linux整合apache和tomcat构建Web服务器
  • *2 echo、printf、mkdir命令的应用
  • .NET Core 中插件式开发实现
  • .NET Core 中的路径问题
  • .Net Core缓存组件(MemoryCache)源码解析
  • .NET MVC、 WebAPI、 WebService【ws】、NVVM、WCF、Remoting
  • .net(C#)中String.Format如何使用
  • .NET微信公众号开发-2.0创建自定义菜单
  • @property括号内属性讲解
  • @RequestMapping处理请求异常
  • @Transactional事务注解内含乾坤?