esp32c3开发板通过micropython的mqtt库连MQTT物联网消息服务器
MQTT介绍
MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息协议,旨在设备之间进行通信,尤其是在网络条件较差的情况下。MQTT v3.1.1 和 MQTT v5 是该协议的两个主要版本。
MQTT v3.1.1:
- 优点:
- 成熟和广泛支持:作为较早的版本,v3.1.1 得到了广泛的实现和支持,包括各种客户端库和服务器(代理)。
- 稳定性:由于长时间的使用,v3.1.1 版本的稳定性和可靠性得到了验证。
- 资源消耗低:设计上考虑了低带宽和低功耗设备,因此非常适合物联网(IoT)应用。
- 缺点:
- 功能限制:与 v5 相比,v3.1.1 缺少一些高级功能,如消息的精确一次性传递(Exactly-Once Delivery)和用户属性(User Properties)。
- 可扩展性:v3.1.1 的一些限制可能使得在某些高级场景下的使用受到限制。
MQTT v5:
- 优点:
- 增强的功能:v5 引入了许多新特性,包括消息的精确一次性传递、用户属性、共享订阅(Shared Subscriptions)、动态消息过滤(Dynamic Message Filters)等,这些特性提高了协议的灵活性和可扩展性。
- 更好的错误处理:v5 提供了更详细的错误代码,有助于客户端更好地理解和处理错误情况。
- 改进的会话恢复:v5 改进了会话恢复机制,使得客户端可以在断开连接后更快地恢复状态。
- 缺点:
- 兼容性问题:由于是较新的版本,v5 的支持可能不如 v3.1.1 广泛,这可能导致与旧系统或客户端的不兼容问题。
- 实现复杂性:新特性的引入可能增加了实现的复杂性,对于资源受限的设备来说,这可能是一个挑战。
总的来说,MQTT v3.1.1 由于其成熟度和广泛支持,仍然是许多应用的首选。而 MQTT v5 提供了更多的高级功能和更好的错误处理,适合需要这些特性的新应用。选择哪个版本取决于具体的应用需求、资源限制以及对新特性的需求。随着时间的推移,v5 的支持和采用可能会增加,从而减少兼容性问题。
mqtt服务器软件Mosquitto
当前比较流行的mqtt服务器是:Mosquitto、EMQTT、HiveMQ等,经过短暂的了解,最终决定使用Mosquitto。
FreeBSD下安装
pkg install mosquitto
安装好后提示:
Message from mosquitto-2.0.18:
The mosquitto MQTT Python driver is now provided by net/py-paho-mqtt
FreeBSD下启动服务,若没有写入rc.conf文件,则启动时需要加上onestart
sudo service mosquitto start
sudo service mosquitto onestart
Ubuntu下安装
安装服务器
sudo apt install mosquitto
安装客户端
sudo apt install mosquitto-clients
启动并配置服务
以Ubuntu下为例。
启动服务
可以使用service启动服务:
sudo service mosquitto start
当然一开始不知道,直接使用运行mosquitto命令启动了服务:
mosquitto
1731855204: Warning: Unable to drop privileges to 'mosquitto' because this user does not exist. Trying 'nobody' instead.
1731855204: mosquitto version 2.0.18 starting
1731855204: Using default config.
1731855204: Starting in local only mode. Connections will only be possible from clients running on this machine.
1731855204: Create a configuration file which defines a listener to allow remote access.
1731855204: For more details see https://mosquitto.org/documentation/authentication-methods/
1731855204: Opening ipv4 listen socket on port 1883.
1731855204: Opening ipv6 listen socket on port 1883.
1731855204: mosquitto version 2.0.18 running
后来才知道可以用service启动和停止服务
后来发现端口只绑定了本地ip,要绑定0.0.0.0,则需要修改配置。
客户端测试:
首先在服务器本机测试
执行mosquitto_sub客户端侦听服务:
mosquitto_sub -t "mytopic"
执行mosquitto_pub发布信息
另一个终端执行:
mosquitto_pub -t "mytopic" -m "Hello, MQTT!!"
1731855866: New connection from 127.0.0.1:29987 on port 1883.
1731855866: New client connected from 127.0.0.1:29987 as auto-E0721C4C-5B09-EF6C-E3B3-892DBEDC9C05 (p2, c1, k60).
1731855866: Client auto-E0721C4C-5B09-EF6C-E3B3-892DBEDC9C05 disconnected.
就会发现刚才的信息Hello, MQTT!!被侦听端收到了:
mosquitto_sub -t "mytopic"
Hello, MQTT!!
发送消息的详细命令:
mosquitto_pub -t "mytopic" -m "Hello, MQTTexitlast1" -h "192.168.0.13"
设置了用户验证后,就需要带用户名和口令参数,比如
mosquitto_pub -t "mytopic" -m "Hello, MQTT!!" -h 192.168.0.13 -u ral -P ral
修改mosquitto配置
添加用户
在/etc/mosquitto目录下修改配置文件,修改mosquitto.conf文件,加入这样两句:
allow_anonymous false
password_file /etc/mosquitto/passwd
执行mosquitto_passwd创建用户ral并写入/etc/mosquitto/passwd文件:
sudo mosquitto_passwd -c /etc/mosquitto/passwd ral
Password:
Reenter password:
这样发送和接收信息都需要用户验证。
修改绑定服务到0.0.0.0
在/etc/mosquitto/conf.d目录里创建bindip.conf文件,加入这一句:
bind_address 0.0.0.0
这样服务就能监听0.0.0.0 ,也就是其它非本机也可以连它。
如果原来ufw防火墙没有放开,那么需要放开1883端口:
sudo ufw allow 1883
这时候再测试一下信息:
mosquitto_pub -t 'mytopic' -m 'ehllo' -u 'ral' -P 'ral'
客户端应该能接收到信息:
mosquitto_sub -t "mytopic"
Hello, MQTT!!
重启mosquitto服务
每次修改mosquitto配置后,都要重启服务
sudo service mosquitto restart
带用户验证的测试
消息接收:
# 带上用户验证
mosquitto_sub -t "mytopic" -u 'ral' -P 'ral'
# 或是带上地址
mosquitto_sub -t "mytopic" -u 'ral' -P 'ral' -h '192.168.0.13'
消息发送:
# 带用户验证的消息发送
mosquitto_pub -t 'mytopic' -m 'hello world' -u 'ral' -P 'ral'
# 带上服务器ip地址
mosquitto_pub -t 'mytopic' -m 'hello world2' -u 'ral' -P 'ral' -h '192.168.0.13'
接收端接收到信息:
mosquitto_sub -t "mytopic" -u 'ral' -P 'ral' -h '192.168.0.13'
hello world
证明配置设置的正确,服务器一切正常!
esp32c3开发板配置
esp32c3开发板烧录micropython 交互环境,参见:esp32c3安装micropython环境-CSDN博客
烧录好固件,启动开发板,进入micropython交互环境。参见:esp32-c3开发板开箱第一步:连上usb口看log信息-CSDN博客
开发板启动wifi连上网
交互界面里执行下面代码连wifi,注意wifi的名字和密码需要根据实际情况修改:
import network
import time
nic = network.WLAN(network.STA_IF)
nic.active(True)
# nic.scan()
if not nic.isconnected():nic.connect("wifi名字", "wifi密码")print("Waiting for connection...")while not nic.isconnected():time.sleep(1)print(nic.ipconfig("addr4"))
如果能输出网络信息,那么就证明连上了wifi
>>> print(nic.ipconfig("addr4"))
('192.168.0.104', '255.255.255.0')
开发板接收mqtt消息代码
继续执行esp32c3开发板里的micropython代码:
from umqtt.simple import MQTTClient# 定义 MQTT 代理的地址和端口
SERVER = "192.168.0.13"
PORT = 1883# 定义客户端 ID、用户名和密码
CLIENT_ID = "my_client_id"
USERNAME = "ral"
PASSWORD = "ral"# 定义要订阅的主题
TOPIC = b"mytopic"# 创建 MQTTClient 实例,并传递用户名和密码参数
client = MQTTClient(CLIENT_ID, SERVER, PORT, user=USERNAME, password=PASSWORD)# 连接到 MQTT 代理
client.connect()# 订阅主题
client.subscribe(TOPIC)# 定义消息回调函数
def sub_cb(topic, msg):print("Received message: ", msg)# 设置消息回调函数
client.set_callback(sub_cb)# 进入消息循环
while True:client.wait_msg()
中文会占用输入缓冲区大小,有点干扰输入,所以可以黏贴下面去掉中文注释的代码:
from umqtt.simple import MQTTClientSERVER = "192.168.0.13"
PORT = 1883CLIENT_ID = "my_client_id"
USERNAME = "ral"
PASSWORD = "ral"TOPIC = b"mytopic"client = MQTTClient(CLIENT_ID, SERVER, PORT, user=USERNAME, password=PASSWORD)client.connect()def sub_cb(topic, msg):print("Received message: ", msg)client.set_callback(sub_cb)client.subscribe(TOPIC)while True:client.wait_msg()
不要一次黏贴一大段,可以2-3句黏贴,比如像这句:client = MQTTClient(CLIENT_ID, SERVER, PORT, user=USERNAME, password=PASSWORD) 比较长,就单独黏贴。
开发板运行后,用一个客户端发送消息
# 本机
mosquitto_pub -t 'mytopic' -m 'hello world' -u 'ral' -P 'ral'
# 非本机
mosquitto_pub -t 'mytopic' -m 'hello world2' -u 'ral' -P 'ral' -h '192.168.0.13'
这时候开发板交互界面里就能接收到发送的信息了!
>>> while True:
... client.wait_msg()
...
Received message: b'hello'
48
这样我们这次实践就完成了!
总结
总体是一次非常愉快的esp32c3开发板与mqtt服务器通信的实践操作。但是由于是第一次使用mosquitto,对它的配置不熟悉,同时也是第一次使用micropython里的mqtt模块(umqtt)进行通信,对它也不熟悉,所以这次实践中箭走了很多弯路,碰到很多问题,幸运的是都解决了。
mqtt服务器,用了半天时间选型为mosquitto,大约这就是眼缘吧,毕竟它是eclicps旗下的,而且FreeBSD还有它的pkg包。安装mosquitto后,需要修改其配置,比如添加用户和密码到指定的文件,修改绑定ip到0.0.0.0,在Ubuntu服务器ufw防火墙中放开1883端口。
esp32c3开发板这块,首先需要烧micropython交互环境的固件,然后usb串口登录到micropython的交互界面,输入python代码。先要配置好WiFi启动tcp/ip网络,然后就是调用umqtt模块进行侦听mqtt消息。micropython的缓冲区较小,不能像普通python里面那样一下子可以黏贴太长的代码段,这也需要注意。
调试
esp32c3上mqtt连接失败
其实这是一个大问题,后来是分解成几个小问题一一解决的。
>>> mqtt_client = connect_mqtt()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in connect_mqtt
File "umqtt/simple.py", line 66, in connect
OSError: [Errno 104] ECONNRESET
想起来了,原来是mqtt服务器跨了网段,为了简化测试,后来就用了linux客户端mosquitto_pub和mosquitto_sub -t "mytopic" 先进行测试。(其实esp32的网络模块是可以联网、跨网段通信的)
在同一网段开服务器,还是不行
原来是ufw防火墙没有放开,放开1883端口
sudo ufw allow 1883
发现没有绑定0.0.0.0,修改配置文件/etc/mosquitto/conf.d/bindip.conf,加入这句:
bind_address 0.0.0.0
然后重启服务
sudo service mosquitto restart
用客户端mosquitto_pub再测试有如下报错:
发送信息报错Connection Refused: not authorised.
mosquitto_pub -t "mytopic" -m "Hello, MQTTexitlast1" -h "192.168.0.13"
Connection error: Connection Refused: not authorised.
添加用户:
sudo mosquitto_passwd -c /etc/mosquitto/passwd ral
Password:
Reenter password:
在/etc/mosquitto目录下的mosquitto.conf文件中加入信息:
allow_anonymous false
password_file /etc/mosquitto/passwd
重启服务后测试:
mosquitto_pub -t "mytopic" -m "Hello, MQTT!!" -h 192.168.0.13 -u ral -P ral
终于不报用户验证错了,现在报错:
esp32连mosquitto报错 Subscribe callback is not set
>>> client.subscribe(TOPIC)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "umqtt/simple.py", line 152, in subscribe
AssertionError: Subscribe callback is not set
是那段代码又问题,换代码:
from umqtt.simple import MQTTClientSERVER = "mqtt.eclipse.org"
PORT = 1883CLIENT_ID = "my_client_id"
USERNAME = "my_username"
PASSWORD = "my_password"TOPIC = b"test/topic"SERVER = "192.168.0.13"
PORT = 1883CLIENT_ID = "my_client_id"
USERNAME = "ral"
PASSWORD = "ral"TOPIC = b"mytopic"client = MQTTClient(CLIENT_ID, SERVER, PORT, user=USERNAME, password=PASSWORD)client.connect()def sub_cb(topic, msg):print("Received message: ", msg)client.set_callback(sub_cb)client.subscribe(TOPIC)while True:client.wait_msg()
这个代码就ok了!
esp32 micropython里黏贴python代码有时候会出错
发现黏贴代码到后面就乱了,估计是黏贴长度超限导致的,减少黏贴长度,问题解决。
相关文章:
esp32c3开发板通过micropython的mqtt库连MQTT物联网消息服务器
MQTT介绍 MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息协议,旨在设备之间进行通信,尤其是在网络条件较差的情况下。MQTT v3.1.1 和 MQTT v5 是该协议的两个主要版本。 MQTT v3.1.1: 优点ÿ…...
OceanBase 升级过程研究(4.2.1.6-4.2.1.8)
模拟业务 使用benchmark加载10仓数据模拟业务场景 升级方法 使用滚动升级方式来进行OB升级。该方法前提是OB集群必须满足官方规定的高可用架构(如果 Zone 个数小于 3,滚动升级时则无法构成多数派), 滚动升级的原理就是轮流完成每个ZONE的升级工作,由于…...
ubuntu下怎么设置机器程序开机自启?
在 Ubuntu 中,可以通过多种方法设置程序或脚本在系统启动时自动运行。以下是几种常见方法: 方法 1:使用 crontab crontab 是一个定时任务管理工具,可以用来设置程序在开机时自动运行。 1. 打开终端,编辑当前用户的 …...
Cesium 相机系统
Cesium 的相机系统是其 3D 地球渲染引擎的重要组成部分,它控制用户在虚拟地球上的视图和交互体验。Cesium 的相机系统具备灵活性和强大的功能,允许开发者自定义视图、导航和交互方式。以下是 Cesium 相机系统的主要特点和功能: 1. 相机的基本…...
数据结构(基本概念及顺序表——c语言实现)
基本概念: 1、引入 程序数据结构算法 数据: 数值数据:能够直接参加运算的数据(数值,字符) 非数值数据:不能够直接参加运算的数据(字符串、图片等) 数据即是信息的载…...
ZYNQ程序固化——ZYNQ学习笔记7
一、ZYNQ启动过程 二、 SD卡启动实操 1、对ZYNQ进行配置添加Flash 2、添加SD卡 3、重新生成硬件信息 4、创建vitis工程文件 5、勾选板级支持包 6、对系统工程进行整体编译,生成两个Debug文件,如图所示。 7、插入SD卡,格式化为 8、考入BOOT.…...
labview使用报表工具从数据库导出数据
之前写了一篇labview从数据库导出数据到excel电子表格,但是是基于调用excel的activeX控件,有时候会有一些bug,就比如我工作机就无法显示方法,后面大哥指点才知道没有的原因是excel安装不完整。像我的工作机就没有这个选项。就需要…...
#define定义宏(2)
大家好,今天给大家分享两个技巧。 首先我们应该先了解一下c语言中字符串具有自动连接的特点。注意只有将字符串作为宏参数的时候才可以把字符串放在字符串中。 下面我们来讲讲这两个技巧 1.使用#,把一个宏参数变成对应的字符串。 2.##的作用 可以把位…...
CentOS网络配置
上一篇文章:VMware Workstation安装Centos系统 在CentOS系统中进行网络配置是确保系统能够顺畅接入网络的重要步骤。本文将详细介绍如何配置静态IP地址、网关、DNS等关键网络参数,以帮助需要的人快速掌握CentOS网络配置的基本方法和技巧。通过遵循本文的…...
基于vue框架的的网上宠物交易管理系统46sn1(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
系统程序文件列表 项目功能:用户,宠物分类,宠物信息 开题报告内容 基于Vue框架的网上宠物交易管理系统开题报告 一、研究背景 随着互联网技术的飞速发展和人们生活水平的提高,宠物已成为许多家庭的重要成员。宠物市场的繁荣不仅体现在实体店的遍地开…...
MySQL数据库:SQL语言入门 【2】(学习笔记)
目录 2,DML —— 数据操作语言(Data Manipulation Language) (1)insert 增加 数据 (2)delete 删除 数据 truncate 删除表和数据,再创建一个新表 (3…...
MySQL深度剖析-索引原理由浅入深
什么是索引? 官方上面说索引是帮助MySQL高效获取数据的数据结构,通俗点的说,数据库索引好比是一本书的目录,可以直接根据页码找到对应的内容,目的就是为了加快数据库的查询速度。 索引是对数据库表中一列或多列的值进…...
路径规划——RRT-Connect算法
路径规划——RRT-Connect算法 算法原理 RRT-Connect算法是在RRT算法的基础上进行的扩展,引入了双树生长,分别以起点和目标点为树的根节点同时扩展随机树从而实现对状态空间的快速搜索。在此算法中以两棵随机树建立连接为路径规划成功的条件。并且&…...
数据科学与SQL:如何计算排列熵?| 基于SQL实现
目录 0 引言 1 排列熵的计算原理 2 数据准备 3 问题分析 4 小结 0 引言 把“熵”应用在系统论中的信息管理方法称为熵方法。熵越大,说明系统越混乱,携带的信息越少;熵越小,说明系统越有序,携带的信息越多。在传感…...
Redis/Codis性能瓶颈揭秘:网卡软中断的影响与优化
目录 现象回顾 问题剖析 现场分析 解决方案 总结与反思 1.调整中断亲和性(IRQ Affinity): 2.RPS(Receive Packet Steering)和 RFS(Receive Flow Steering): 近期,…...
微知-DOCA ARGP参数模块的相关接口和用法(config单元、params单元,argp pipe line,回调)
文章目录 1. 背景2. 设置参数的主要流程2.1 初始化2.2 注册某个params的处理方式以及回调函数2.4 定义好前面的params以及init指定config地点后start处理argv 3. 其他4. DOCA ARGP包相关4.1 主要接口4.2 DOCA ARGP的2个rpm包4.2.1 doca-sdk-argp-2.9.0072-1.el8.x86_64.rpm4.2.…...
PostgreSQL高可用Patroni安装(超详细)
目录 一 安装Patroni 0 Patroni 对Python的版本要求 1 卸载原来的Python 3.6 版本 2 安装Python 3.7 之上版本 3 安装依赖 psycopg3 4 安装patroni 5 卸载 patroni 二 安装ETCD 1 使用 yum 安装 etcd 2 etcd 配置文件 3 管理 etcd 4 设置密码 5 常用命令 三 安装…...
mcu之,armv7架构,contex-M4系列,时钟树,中断,IO架构(一)
写这篇文章的目的,是记录一下arm架构的32mcu,方便记忆芯片架构原理,方便我展开对,BootLoader的研究。 arm架构,时钟树,先做个记录,有空写。...
论文解析:基于区块链的去中心化服务选择,用于QoS感知的云制造(四区)
目录 论文解析:基于区块链的去中心化服务选择,用于QoS感知的云制造(四区) 基于区块链的去中心化云制造服务选择方法 一、核心内容概述 二、核心创新点及原理与理论 三、实验与理论分析 PBFT(实用拜占庭容错) 论文解析:基于区块链的去中心化服务选择,用于QoS感知的…...
详细解析STM32 GPIO引脚的8种模式
目录 一、输入浮空(Floating Input):GPIO引脚不连接任何上拉或下拉电阻,处于高阻态 1.浮空输入的定义 2.浮空输入的特点 3.浮空输入的应用场景 4.浮空输入的缺点 5.典型配置方式 6.注意事项 二、输入上拉(Inpu…...
【hacker送书第16期】Python数据分析、挖掘与可视化、AI全能助手ChatGPT职场工作效率提升技巧与案例
解锁数据分析与AI应用的双重秘密:全面推广《Python数据分析、挖掘与可视化从入门到精通》与《AI全能助手ChatGPT职场工作效率提升技巧与案例》 前言Python数据分析、挖掘与可视化从入门到精通💕内容简介获取方式 AI全能助手ChatGPT职场工作效率提升技巧与…...
翼鸥教育:从OceanBase V3.1.4 到 V4.2.1,8套核心集群升级实践
引言:自2021年起,翼鸥教育便开始应用OceanBase社区版,两年间,先后部署了总计12套生产集群,其中核心集群占比超过四分之三,所承载的数据量已突破30TB。自2022年10月,OceanBase 社区发布了4.2.x 版…...
WebGIS开发中不同坐标系坐标转换问题
在 JavaScript 中,使用 proj4 库进行坐标系转换是一个非常常见的操作。proj4 是一个支持多种坐标系的 JavaScript 库,提供了从一种坐标系到另一种坐标系的转换功能。 以下是使用 proj4 进行坐标系转换的基本步骤: 1. 安装 proj4 你可以通过…...
【青牛科技】视频监控器应用
1、简介: 我司安防产品广泛应用在视频监控器上,产品具有性能优良,可 靠性高等特点。 2、图示: 实物图如下: 3、具体应用: 标题:视频监控器应用 简介:视频监控器工作原理是光&#x…...
AWTK-WIDGET-WEB-VIEW 实现笔记 (3) - MacOS
MacOS 上实现 AWTK-WIDGET-WEB-VIEW 有点麻烦,主要原因是没有一个简单的办法将一个 WebView 嵌入到一个窗口中。所以,我们只能通过创建一个独立的窗口来实现。 1. 创建窗口 我对 Object-C 不熟悉,也不熟悉 Cocoa 框架,在 ChatGPT…...
PgSQL即时编译JIT | 第1期 | JIT初识
PgSQL即时编译JIT | 第1期 | JIT初识 JIT是Just-In-Time的缩写,也就是说程序在执行的时候生成可以执行的代码,然后执行它。在介绍JIT之前,需要说下两种执行方式:解释执行和编译执行。其中解释执行是通过解释器,将代码逐…...
Go小记:使用Go实现ssh客户端
一、前言 SSH(Secure Shell)是一种用于在不安全网络上安全访问远程计算机的网络协议。它通过加密的方式提供远程登录会话和其他网络服务,保证通信的安全性和数据的完整性。 本文使用golang.org/x/crypto/ssh包来实现SSH客户端 可以通过go …...
Nginx Spring boot指定域名跨域设置
1、Nginx配置跨域: server {listen 80;server_name your-backend-service.com;location / {proxy_pass http://localhost:8080; # Spring Boot应用的内部地址proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-F…...
深入理解Redis(七)----Redis实现分布式锁
基于Redis的实现方式 1、选用Redis实现分布式锁原因: (1)Redis有很高的性能; (2)Redis命令对此支持较好,实现起来比较方便 2、使用命令介绍: (1)SETNX SETNX …...
Database Advantages (数据库系统的优点)
数据库管理系统(DBMS)提供了一种结构化的方式来存储、管理和访问数据,与传统的文件处理系统相比,数据库提供了许多显著的优点。以下是数据库系统的主要优势: 1. Data Integrity (数据完整性) 概念:数据完整…...
廊坊市网站推广/江苏百度推广代理商
1.安装Head插件 什么是Head ealsticsearch只是后端提供各种api,那么怎么直观的使用它呢?elasticsearch-head将是一款专门针对于elasticsearch的客户端工具 elasticsearch-head配置包,下载地址:https://github.com/mobz/elasticsea…...
建设工程合同约定的质量目标/绍兴网站快速排名优化
shirio的功能 Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。这不就是我们想要的嘛,而且Shiro的API也是非常简…...
在北京哪家公司建网站合适/通州优化公司
二毛道家源流经典之一《黄帝内经》主张“食为性命之基”,并提倡“五谷为养,五果为助,五畜为益,五菜为充”。如果饮食不当,五味不调,饮食亦为疾病之源,主张通过对食物的挑选、搭配,达…...
手机怎么建网站/杭州优化公司在线留言
The following are some english patterns I’ve learned today. Iwrote down them in order to restudy later. 1. have a bone in one’s throat 难以启齿 2. Don’t take it to heart. 别往心里去。 3. I just couldn’t help it. 我只是控制不住。 4. Let’s face it. 面对…...
webstation做网站/seo怎么优化武汉厂商
PHP CURL模拟RESTFul风格 HTTP常规的请求方式:GET,POST,而RESTFull方法有: GET, POST, PUT, PATCH, DELETE等几种。要支持其他方法怎么办? 我们基于PHP强大的CURL函数封装一个:这里我只增加PUT和DELETE,可以扩展: <?php # php curl 封装 namespace Great\lib; i…...
做一个兼职app多少钱/seo排名工具有哪些
整理 | 孙胜 出品 | CSDN(ID:CSDNnews) FTP是一种国际公认的文件传输协议,协议最初标准是于 1971 年的FRC 114转化而来,已有半个世纪历史。随着Mozilla浏览器关闭了Firefox浏览器的FTP协议,浏览器舍弃FTP功…...