本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
安全套接字库
该库托管在 Amazon-FreeRTOS 存储库中,该存储库已过时。建议您在创建新项目时从这里开始。如果您已经有一个基于现已弃用的 Amazon-FreeRTOS 存储库的 FreeRTOS 项目,请参阅亚马逊 FreeRTOS Github 存储库迁移指南。
概览
您可以使用 FreeRTOS 安全套接字库来创建安全通信的嵌入式应用程序。该库旨在使来自各种网络编程背景的软件开发人员能够轻松掌握。
FreeRTOS 安全套接字库基于伯克利套接字接口,还有一个通过 TLS 协议提供的额外安全通信选项。有关 FreeRTOS 安全套接字库和伯克利套接字接口之间差异的信息,请参阅SOCKETS_SetSockOpt
《安全套接字 API 参考》。
目前,FreeRTOS 安全套接字仅支持客户端 API 以及服务器端Bind
API 的轻量级 IP (LWIP)
依赖项和要求
FreeRTOS 安全套接字库依赖于 TCP/IP 堆栈和 TLS 实现。FreeRTOS 的端口通过以下三种方式之一实现:
-
TCP/IP 和 TLS 的自定义实现
-
TCP/IP 的自定义实现,以及使用 mbedTLS 的 FreeRTOS TLS
层
下面的依赖关系图显示了 FreeRTOS 安全套接字库中包含的参考实现。此参考实施通过以太网和 Wi-Fi 支持 TLS 和 TCP/IP,并将 FreeRTOS+TCP 和 mbedTLS 作为依赖项。有关 FreeRTOS TLS 层的更多信息,请参阅传输层安全。

功能
FreeRTOS 安全套接字库功能包括:
-
一个基于 Berkeley 套接字的标准接口
-
用于发送和接收数据的线程安全的 API
-
Easy-to-enable TLS
故障排除
错误代码
FreeRTOS 安全套接字库返回的错误代码是负值。有关每个错误代码的更多信息,请参阅安全套接字 API 参考中的安全套接字错误代码。
如果 FreeRTOS Secure Sockets API 返回错误代码CoreMQTLARARARAR,则依赖于 FreeRTOS 安全套接字库的会返回错误代码AWS_IOT_MQTT_SEND_ERROR
。
开发人员支持
FreeRTOS 安全套接字库包括两个用于处理 IP 地址的帮助器宏:
SOCKETS_inet_addr_quick
-
此宏将表示为四个独立数字八位字节的 IP 地址转换为按网络字节顺序表示为 32 位数字的 IP 地址。
SOCKETS_inet_ntoa
-
此宏将按网络字节顺序表示为 32 位数字的 IP 地址转换为用十进制表示的字符串。
使用限制
FreeRTOS 安全套接字库仅支持 TCP 套接字。不支持 UDP 套接字。
FreeRTOS 安全套接字库不支持服务器 API,服务器端Bind
API 的轻量级 IP (LWIP)
初始化
要使用 FreeRTOS 安全套接字库,您需要初始化该库及其依赖关系。要初始化安全套接字库,请在应用程序中使用以下代码:
BaseType_t xResult = pdPASS; xResult = SOCKETS_Init();
必须单独初始化相关库。例如,如果 FreeRTOS+TCP 是一个依赖项,则您还需要在应用程序中调用 FreeRTOS_IPInit
API 参考
有关完整的 API 参考资料,请参阅安全套接字 API 参考。
示例用法
以下代码可将客户端连接到服务器。
#include "aws_secure_sockets.h" #define configSERVER_ADDR0 127 #define configSERVER_ADDR1 0 #define configSERVER_ADDR2 0 #define configSERVER_ADDR3 1 #define configCLIENT_PORT 443 /* Rx and Tx timeouts are used to ensure the sockets do not wait too long for * missing data. */ static const TickType_t xReceiveTimeOut = pdMS_TO_TICKS( 2000 ); static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 2000 ); /* PEM-encoded server certificate */ /* The certificate used below is one of the Amazon Root CAs.\ Change this to the certificate of your choice. */ static const char cTlsECHO_SERVER_CERTIFICATE_PEM[] = "-----BEGIN CERTIFICATE-----\n" "MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5\n" "MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g\n" "Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG\n" "A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg\n" "Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl\n" "ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j\n" "QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr\n" "ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr\n" "BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM\n" "YyRIHN8wfdVoOw==\n" "-----END CERTIFICATE-----\n"; static const uint32_t ulTlsECHO_SERVER_CERTIFICATE_LENGTH = sizeof( cTlsECHO_SERVER_CERTIFICATE_PEM ); void vConnectToServerWithSecureSocket( void ) { Socket_t xSocket; SocketsSockaddr_t xEchoServerAddress; BaseType_t xTransmitted, lStringLength; xEchoServerAddress.usPort = SOCKETS_htons( configCLIENT_PORT ); xEchoServerAddress.ulAddress = SOCKETS_inet_addr_quick( configSERVER_ADDR0, configSERVER_ADDR1, configSERVER_ADDR2, configSERVER_ADDR3 ); /* Create a TCP socket. */ xSocket = SOCKETS_Socket( SOCKETS_AF_INET, SOCKETS_SOCK_STREAM, SOCKETS_IPPROTO_TCP ); configASSERT( xSocket != SOCKETS_INVALID_SOCKET ); /* Set a timeout so a missing reply does not cause the task to block indefinitely. */ SOCKETS_SetSockOpt( xSocket, 0, SOCKETS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof( xReceiveTimeOut ) ); SOCKETS_SetSockOpt( xSocket, 0, SOCKETS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) ); /* Set the socket to use TLS. */ SOCKETS_SetSockOpt( xSocket, 0, SOCKETS_SO_REQUIRE_TLS, NULL, ( size_t ) 0 ); SOCKETS_SetSockOpt( xSocket, 0, SOCKETS_SO_TRUSTED_SERVER_CERTIFICATE, cTlsECHO_SERVER_CERTIFICATE_PEM, ulTlsECHO_SERVER_CERTIFICATE_LENGTH ); if( SOCKETS_Connect( xSocket, &xEchoServerAddress, sizeof( xEchoServerAddress ) ) == 0 ) { /* Send the string to the socket. */ xTransmitted = SOCKETS_Send( xSocket, /* The socket receiving. */ ( void * )"some message", /* The data being sent. */ 12, /* The length of the data being sent. */ 0 ); /* No flags. */ if( xTransmitted < 0 ) { /* Error while sending data */ return; } SOCKETS_Shutdown( xSocket, SOCKETS_SHUT_RDWR ); } else { //failed to connect to server } SOCKETS_Close( xSocket ); }
有关完整示例,请参阅安全套接字 Echo 客户端演示。
移植
FreeRTOS 安全套接字依赖于 TCP/IP 堆栈和 TLS 实现。根据您的堆栈,要移植安全套接字库,您可能需要移植以下项目中的部分项目:
-
FreeRTOS+TCP
TCP/IP 堆栈 -
这些区域有: corep (缓冲内存)
-
这些区域有: 传输层安全
有关移植的更多信息,请参阅 FreeRTOS 移植指南中的移植安全套接字库。