

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Secure Sockets 程式庫
<a name="secure-sockets"></a>

**重要**  <a name="deprecation-message-library"></a>
此程式庫託管在已棄用的 Amazon-FreeRTOS 儲存庫上。我們建議您在建立新專案時從[這裡開始](freertos-getting-started-modular.md)。如果您已經有以現在已棄用的 Amazon-FreeRTOS 儲存庫為基礎的現有 FreeRTOS 專案，請參閱 [Amazon-FreeRTOS Github 儲存庫遷移指南](github-repo-migration.md)。 FreeRTOS 

## 概觀
<a name="freertos-secure-sockets-overview"></a>

您可以使用 FreeRTOS [Secure Sockets](https://docs.aws.amazon.com/freertos/latest/lib-ref/html2/secure_sockets/index.html) 程式庫來建立安全通訊的內嵌應用程式。此程式庫的設計旨在讓來自各種網路程式設計背景的軟體開發人員都能夠輕鬆上線。

FreeRTOS Secure Sockets 程式庫是以 Berkeley 通訊端介面為基礎，具有 TLS 通訊協定的其他安全通訊選項。如需有關 FreeRTOS Secure Sockets 程式庫與 Berkeley 通訊端介面之間差異的資訊，請參閱 [Secure Sockets API 參考](https://docs.aws.amazon.com/freertos/latest/lib-ref/html2/secure_sockets/index.html)`SOCKETS_SetSockOpt`中的 。

**注意**  
目前，FreeRTOS Secure Sockets 僅支援用戶端 APIs，以及伺服器端 `Bind` API 的[輕量型 IP (lwIP)](https://savannah.nongnu.org/projects/lwip/) 實作。

## 相依性和要求
<a name="freertos-secure-sockets-dependencies"></a>

FreeRTOS Secure Sockets 程式庫取決於 TCP/IP 堆疊和 TLS 實作。FreeRTOS 連接埠以下列三種方式之一滿足這些相依性：
+ 同時自訂實作 TCP/IP 及 TLS
+ TCP/IP 的自訂實作，以及具有 mbedTLS 的 FreeRTOS TLS layer [mbedTLS](https://en.wikipedia.org/wiki/Mbed_TLS)
+ [FreeRTOS\$1TCP](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html) 和具有 mbedTLS 的 FreeRTOS TLS 層 [mbedTLS](https://en.wikipedia.org/wiki/Mbed_TLS)

以下相依性圖表顯示 FreeRTOS Secure Sockets 程式庫隨附的參考實作。此參考實作支援透過乙太網路和 Wi-Fi 的 TLS 和 TCP/IP，搭配做為相依性的 FreeRTOS\$1TCP 和 mbedTLS。如需 FreeRTOS TLS layer 的詳細資訊，請參閱 [Transport Layer Security](security-tls.md)。

![\[使用 FreeRTOS+TCP、TLS Layer 和 TLS 元件的 Secure Sockets Library 架構。\]](http://docs.aws.amazon.com/zh_tw/freertos/latest/userguide/images/sockets-dependencies.png)


## 功能
<a name="freertos-secure-sockets-features"></a>

FreeRTOS Secure Sockets 程式庫功能包括：
+ 標準 Berkeley 通訊端型界面
+ 用於傳送和接收資料的執行緒安全 API
+ 方便啟用 TLS

## 疑難排解
<a name="freertos-secure-sockets-troubleshooting"></a>

### 錯誤代碼
<a name="w2aac31b9c13c45c15b5"></a>

FreeRTOS Secure Sockets 程式庫傳回的錯誤代碼為負值。如需每個錯誤碼的詳細資訊，請參閱 [Secure Sockets API 參考](https://docs.aws.amazon.com/freertos/latest/lib-ref/html2/secure_sockets/index.html)中的 Secure Sockets 錯誤碼。

**注意**  
如果 FreeRTOS Secure Sockets API 傳回錯誤碼，則[coreMQTT 程式庫](coremqtt.md)取決於 FreeRTOS Secure Sockets 程式庫的 會傳回錯誤碼 `AWS_IOT_MQTT_SEND_ERROR`。

## 開發人員支援
<a name="freertos-secure-sockets-support"></a>

FreeRTOS Secure Sockets 程式庫包含兩個用於處理 IP 地址的協助程式巨集：

**`SOCKETS_inet_addr_quick`**  
此巨集會依網路位元組順序將以四個單獨數字八位元表示的 IP 地址轉換為以 32 位元數字表示的 IP 地址。

**`SOCKETS_inet_ntoa`**  
此巨集會依網路位元組順序將以 32 位元數字表示的 IP 地址轉換為以小數點表示法表示的字串。

## 使用限制
<a name="freertos-secure-sockets-restrictions"></a>

FreeRTOS Secure Sockets 程式庫僅支援 TCP 通訊端。不支援 UDP 通訊端。

FreeRTOS Secure Sockets 程式庫不支援伺服器 APIs，但伺服器端 `Bind` API 的[輕量型 IP (lwIP)](https://savannah.nongnu.org/projects/lwip/) 實作除外。支援用戶端 APIs。

## 初始化
<a name="freertos-secure-sockets-initialization"></a>

若要使用 FreeRTOS Secure Sockets 程式庫，您需要初始化程式庫及其相依性。若要初始化 Secure Sockets 程式庫，請在您的應用程式中使用下列程式碼：

```
BaseType_t xResult = pdPASS;
xResult = SOCKETS_Init();
```

必須個別初始化相依程式庫。例如，如果 FreeRTOS\$1TCP 是相依性，則您也需要在應用程式中呼叫 [https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/API/FreeRTOS_IPInit.html](https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/API/FreeRTOS_IPInit.html)。

## API 參考
<a name="freertos-secure-sockets-api"></a>

如需完整的 API 參考，請參閱 [ Secure Sockets API 參考](https://docs.aws.amazon.com/freertos/latest/lib-ref/html2/secure_sockets/index.html)。

## 範例使用方式
<a name="freertos-secure-sockets-example"></a>

以下程式碼會將用戶端連接到伺服器。

```
#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 );
}
```

如需完整範例，請參閱 [Secure Sockets echo 用戶端示範](secure-sockets-demo.md)。

## 移植
<a name="freertos-secure-sockets-porting"></a>

FreeRTOS Secure Sockets 取決於 TCP/IP 堆疊和 TLS 實作。根據您的堆疊，若要移植 Secure Sockets 程式庫，您可能需要移植下列一些項目：
+ [FreeRTOS\$1TCP](https://freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/index.html) TCP/IP 堆疊
+ [corePKCS11 程式庫](security-pkcs.md)
+ [Transport Layer Security](security-tls.md)

如需移植的詳細資訊，請參閱 FreeRTOS [移植指南中的移植 Secure Sockets](https://docs.aws.amazon.com/freertos/latest/portingguide/afr-porting-ss.html) Library。