success to establish tcp, fd=54 mbedtls_ssl_handshake error, res: -0x6800 establish mbedtls connection with server(host='a1ul4uS7RfV.iot-as-mqtt.cn-shanghai.aliyuncs.com', port=[443]) tcp_connect: can only connect from state CLOSED
时间: 2024-03-21 10:43:18 浏览: 243
这个错误提示是在进行 TLS 握手时出现的,可能是由于以下原因导致的:
1. 证书验证失败。在进行 TLS 握手时,客户端会验证服务器的证书是否合法。如果证书不合法,就会导致握手失败。您可以尝试关闭证书验证,或者确认您的证书是否正确。
2. 网络连接不稳定。握手过程需要进行多次网络通信,如果网络连接不稳定,也会导致握手失败。
3. 服务器端口未开放。如果服务器端口未开放,客户端就无法连接到服务器。
针对这个错误,您可以尝试以下方法:
1. 确认您的证书是否正确,并尝试关闭证书验证。在 MQTTClient 的构造函数中,将 ssl 参数设置为 False,即可关闭证书验证。
```python
client = MQTTClient(CLIENT_ID, SERVER, PORT, USER_NAME, PASSWORD, ssl=False)
```
2. 检查网络连接是否正常。您可以尝试使用 ping 命令测试网络连接是否通畅。
3. 确认服务器端口是否开放。您可以尝试使用 telnet 命令测试服务器端口是否可以连接。
如果以上方法都无法解决问题,可以尝试查看更详细的错误日志,以便更好地定位问题。
相关问题
用mbedtls 发送multipart/form-data post{ "did": "string", "productToken": "string", "state": 0 }
mbedtls是一个轻量级的加密库,主要提供了TLS/SSL协议实现和加密算法的实现。它并不直接提供发送HTTP请求的功能,但可以结合其他HTTP库(如libcurl)来发送HTTP请求。
对于multipart/form-data格式的POST请求,需要在请求头中指定Content-Type为multipart/form-data,并在请求体中按照格式组织数据。具体实现方法可以参考下面的示例代码:
```c
#include "mbedtls/net_sockets.h"
#include "mbedtls/ssl.h"
#include "mbedtls/error.h"
#include "mbedtls/debug.h"
#include <stdio.h>
#include <string.h>
#define HOSTNAME "example.com"
#define PORT "443"
#define REQUEST_BODY "--boundary\r\nContent-Disposition: form-data; name=\"did\"\r\n\r\nstring\r\n--boundary\r\nContent-Disposition: form-data; name=\"productToken\"\r\n\r\nstring\r\n--boundary\r\nContent-Disposition: form-data; name=\"state\"\r\n\r\n0\r\n--boundary--\r\n"
int main()
{
int ret;
mbedtls_net_context server_fd;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;
mbedtls_x509_crt cacert;
mbedtls_net_init(&server_fd);
mbedtls_ssl_init(&ssl);
mbedtls_ssl_config_init(&conf);
mbedtls_x509_crt_init(&cacert);
ret = mbedtls_x509_crt_parse_file(&cacert, "ca.crt");
if (ret != 0) {
printf("failed to parse ca.crt, ret=%d\n", ret);
goto exit;
}
ret = mbedtls_net_connect(&server_fd, HOSTNAME, PORT, MBEDTLS_NET_PROTO_TCP);
if (ret != 0) {
printf("failed to connect, ret=%d\n", ret);
goto exit;
}
ret = mbedtls_ssl_config_defaults(&conf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
if (ret != 0) {
printf("failed to set ssl config defaults, ret=%d\n", ret);
goto exit;
}
mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_REQUIRED);
mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
ret = mbedtls_ssl_setup(&ssl, &conf);
if (ret != 0) {
printf("failed to setup ssl, ret=%d\n", ret);
goto exit;
}
mbedtls_ssl_set_hostname(&ssl, HOSTNAME);
mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
printf("failed to handshake with server, ret=%d\n", ret);
goto exit;
}
}
printf("handshake success!\n");
// send POST request
const char *request_fmt =
"POST /api/v1/device/bind HTTP/1.1\r\n"
"Host: %s:%s\r\n"
"Content-Type: multipart/form-data; boundary=boundary\r\n"
"Content-Length: %d\r\n\r\n%s";
char request_buf[4096];
int request_len = snprintf(request_buf, sizeof(request_buf), request_fmt, HOSTNAME, PORT, strlen(REQUEST_BODY), REQUEST_BODY);
while ((ret = mbedtls_ssl_write(&ssl, (const unsigned char *)request_buf, request_len)) <= 0) {
if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) {
continue;
}
printf("failed to write data to server, ret=%d\n", ret);
goto exit;
}
exit:
mbedtls_x509_crt_free(&cacert);
mbedtls_ssl_free(&ssl);
mbedtls_ssl_config_free(&conf);
mbedtls_net_free(&server_fd);
return 0;
}
```
相关问题:
1. 如何使用mbedtls发送HTTP请求?
2. multipart/form-data格式的POST请求具体怎么组织数据?
3. 如何解析HTTP响应?
stm32使用mbedtls实现https
STM32微控制器使用Mbed TLS (以前称为 mbedtls) 来支持HTTPS协议,这是一种安全通信协议,基于TCP/IP,用于在客户端(如智能手机、嵌入式设备)和服务器之间传输数据,特别是在互联网上进行敏感信息交换。
以下是使用Mbed TLS在STM32上实现HTTPS的基本步骤:
1. **库配置**:首先,需要将Mbed TLS库添加到你的STM32项目中,并进行适当的初始化,包括配置加密算法、哈希函数等。
```c
#include "mbedtls/config.h"
// ...其他头文件
mbedtls_config config;
mbedtls_ssl_context ssl;
```
2. **证书管理**:你需要准备公钥证书(.pem格式)以及私钥(.key格式),并使用Mbed TLS提供的函数加载它们。
```c
const char *cert_pem = "path_to_your_certificate.pem";
const char *private_key_pem = "path_to_your_private_key.pem";
mbedtls_pk_context pk;
if (mbedtls_pk_parse_key(&pk, private_key_pem, NULL, NULL) != 0) {
// 处理错误
}
mbedtls_x509_crt cacert;
if (mbedtls_x509_crt_parse(&cacert, cert_pem) != 0) {
// 处理错误
}
```
3. **SSL套接字初始化**:创建一个SSL上下文,并设置服务器地址和其他参数。
```c
if (mbedtls_ssl_init(&ssl) != 0) {
// 处理错误
}
if (mbedtls_ssl_setup(&ssl, &config) != 0) {
// 处理错误
}
ssl.server_name = (uint8_t *)"your_server.example.com"; // 设置服务器域名
```
4. **连接建立**:尝试连接到服务器,通过`mbedtls_ssl_connect()`函数开始TLS握手过程。
```c
if (mbedtls_ssl_handshake(&ssl) != MBEDTLS_SUCCESS) {
// 处理错误
}
```
5. **数据传输**:一旦连接成功,就可以使用普通的TCP方式进行读写操作,同时保护数据的安全性。
6. **关闭连接**:完成数据传输后,记得使用`mbedtls_ssl_close_notify()`和`mbedtls_ssl_free(&ssl)`释放资源。
阅读全文