{"id":3494,"date":"2025-04-05T23:08:37","date_gmt":"2025-04-05T15:08:37","guid":{"rendered":"https:\/\/saludpcb.com\/zh\/?p=3494"},"modified":"2025-09-26T06:15:50","modified_gmt":"2025-09-25T22:15:50","slug":"esp32-smtp-gmail","status":"publish","type":"post","link":"https:\/\/saludpcb.com\/zh\/esp32-smtp-gmail\/","title":{"rendered":"\u7cbe\u901a ESP32 SMTP | \u4f7f\u7528 GMail \u767c\u9001\u90f5\u4ef6"},"content":{"rendered":"\n<hr class=\"wp-block-separator alignwide has-text-color has-palette-color-1-color has-alpha-channel-opacity has-palette-color-1-background-color has-background is-style-wide\"\/>\n\n\n\n<p><strong>ESP32 SMTP \u6574\u5408 Gmail \u5bc4\u4fe1\u529f\u80fd<\/strong>\u662f IoT \u5c08\u6848\u4e2d\u4e0d\u53ef\u6216\u7f3a\u7684\u5be6\u7528\u6280\u80fd\u4e4b\u4e00\u3002\u672c\u7bc7\u5b8c\u6574\u6559\u5b78\u5c07\u6db5\u84cb Wi-Fi \u9023\u7dda\u3001TLS \u52a0\u5bc6\u9023\u7dda Gmail\u3001SMTP \u547d\u4ee4\u4ea4\u63e1\u3001Base64 \u8a8d\u8b49\u7b49\u6280\u8853\u7d30\u7bc0\uff0c\u9069\u5408\u5e0c\u671b\u9032\u4e00\u6b65\u5f37\u5316 ESP32 \u61c9\u7528\u80fd\u529b\u7684\u958b\u767c\u8005\u3002<\/p>\n\n\n\n<p>\u60f3\u77e5\u9053 <strong>ESP32 \u5982\u4f55\u900f\u904e SMTP \u50b3\u9001 Gmail \u90f5\u4ef6<\/strong>\uff1f\u9019\u7bc7\u6559\u5b78\u5c07\u5e36\u4f60\u4e00\u6b65\u6b65\u5f9e\u9023\u63a5 Wi-Fi \u5230\u6210\u529f\u767c\u9001\u7b2c\u4e00\u5c01\u90f5\u4ef6\uff0c\u5b8c\u6574\u89e3\u6790 Gmail SMTP \u8a8d\u8b49\u3001TLS \u5b89\u5168\u9023\u7dda\u8207\u5bc4\u4ef6\u6d41\u7a0b\uff01<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/saludpcb.com\/zh\/wp-content\/uploads\/2025\/04\/Master-ESP32-SMTP-Effortlessly-Send-Emails-with-Gmail.jpg\" alt=\"ESP32 SMTP\" class=\"wp-image-3504\" title=\"\" srcset=\"https:\/\/saludpcb.com\/zh\/wp-content\/uploads\/2025\/04\/Master-ESP32-SMTP-Effortlessly-Send-Emails-with-Gmail.jpg 1024w, https:\/\/saludpcb.com\/zh\/wp-content\/uploads\/2025\/04\/Master-ESP32-SMTP-Effortlessly-Send-Emails-with-Gmail-768x768.jpg 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>\u5167\u5bb9<\/h2><nav><ul><li class=\"\"><a href=\"#\u4ec0\u9ebc\u662f-modbus\uff1f\">\u4ec0\u9ebc\u662f SMTP\uff1f<\/a><\/li><li class=\"\"><a href=\"#\u74b0\">\u958b\u767c\u74b0\u5883<\/a><\/li><li class=\"\"><a href=\"#esp-32-modbus-rtu-slave\uff08\u5f9e\u6a5f\uff09\">\u914d\u7f6e Wi-Fi \u9023\u63a5<\/a><\/li><li class=\"\"><a href=\"#esp-32-modbus-rtu-master\">Wi-Fi \u4e8b\u4ef6\u8655\u7406<\/a><\/li><li class=\"\"><a href=\"#base-64-\u7de8\u78bc\u51fd\u6578\">\u5efa\u7acb ESP32 SMTP \u9023\u63a5<\/a><\/li><li class=\"\"><a href=\"#google-\u61c9\u7528\u5bc6\u78bc\">Google \u61c9\u7528\u5bc6\u78bc<\/a><\/li><li class=\"\"><a href=\"#\u5b8c\u6574\u7a0b\u5f0f\u78bc\">\u5b8c\u6574\u7684 ESP32 SMTP \u7a0b\u5f0f\u78bc<\/a><\/li><li class=\"\"><a href=\"#\u7de8\u8b6f\u548c\u71d2\u9304\">\u7de8\u8b6f\u548c\u71d2\u9304<\/a><\/li><li class=\"\"><a href=\"#check-your-inbox\">\u6aa2\u67e5\u4f60\u7684\u6536\u4ef6\u5323<\/a><\/li><li class=\"\"><a href=\"#\u7d50\u8ad6\">\u7d50\u8ad6<\/a><\/li><\/ul><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"\u4ec0\u9ebc\u662f-modbus\uff1f\">\u4ec0\u9ebc\u662f SMTP\uff1f<\/h2>\n\n\n\n<p>SMTP\uff08Simple Mail Transfer Protocol\uff0c\u7c21\u55ae\u90f5\u4ef6\u50b3\u8f38\u5354\u5b9a\uff09\u662f\u4e00\u7a2e<strong>\u7528\u4f86\u50b3\u9001\u96fb\u5b50\u90f5\u4ef6\u7684\u7db2\u969b\u7db2\u8def\u6a19\u6e96\u5354\u5b9a<\/strong>\u3002\u7c21\u55ae\u4f86\u8aaa\uff0c\u5b83\u5c31\u662f\u96fb\u90f5\u7684\u300c\u90f5\u5dee\u300d\uff0c\u8ca0\u8cac\u628a\u4f60\u7684\u90f5\u4ef6\u5f9e\u767c\u4ef6\u4eba\u9019\u7aef\uff0c\u50b3\u905e\u5230\u6536\u4ef6\u4eba\u7684\u90f5\u4ef6\u4f3a\u670d\u5668\u3002<\/p>\n\n\n\n<p>ESP32 \u662f\u4e00\u6b3e\u652f\u63f4 Wi-Fi \u7684\u5fae\u63a7\u5236\u5668\uff0c\u6211\u5011\u5c31\u53ef\u4ee5\u4f7f\u7528 ESP32 <strong>SMTP \u642d\u914d Gmail \u6216\u5176\u4ed6\u90f5\u4ef6\u670d\u52d9\uff0c\u8b93 ESP32 \u81ea\u52d5\u5bc4\u51fa Email<\/strong>\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"\u74b0\">\u958b\u767c\u74b0\u5883<\/h2>\n\n\n\n<p>\u5728\u958b\u59cb\u7de8\u7a0b\u4e4b\u524d\uff0c\u8acb\u78ba\u4fdd\u5df2\u5b8c\u6210\u4ee5\u4e0b\u6e96\u5099\u5de5\u4f5c\uff1a<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/saludpcb.com\/zh\/esp32-tutorial-how-to-create-an-esp32-project-with-vscode\/\">\u5b89\u88dd ESP-IDF \u958b\u767c\u74b0\u5883<\/a> (\u81f3\u5c11\u7248\u672c v4.4 \u6216\u66f4\u9ad8)\u3002<\/li>\n\n\n\n<li><a href=\"https:\/\/saludpcb.com\/zh\/esp32-devkit-module-pinout\/\">ESP32 \u958b\u767c\u677f<\/a>\u3002<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"esp-32-modbus-rtu-slave\uff08\u5f9e\u6a5f\uff09\">\u914d\u7f6e Wi-Fi \u9023\u63a5<\/h2>\n\n\n\n<p>ESP32 \u9700\u8981\u9023\u63a5\u81f3\u4e00\u500b Wi-Fi \u7db2\u8def\u624d\u80fd\u5b58\u53d6\u7db2\u969b\u7db2\u8def\uff0c\u4e26\u9023\u7dda\u81f3 Gmail \u7684 SMTP \u4f3a\u670d\u5668\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">\/\/ WiFi credentials - replace with your actual network information\n#define WIFI_SSID \"your_wifi_ssid\"\n#define WIFI_PASS \"your_wifi_password\"\n\n\/\/ Function to initialize and connect to WiFi in station mode\nvoid wifi_init_sta() {\n    \/\/ Create default WiFi station network interface\n    esp_netif_create_default_wifi_sta();\n\n    \/\/ Initialize WiFi with default configuration\n    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();\n    ESP_ERROR_CHECK(esp_wifi_init(&amp;cfg));\n\n    \/\/ Configure WiFi station settings\n    wifi_config_t wifi_config = {\n        .sta = {\n            .ssid = WIFI_SSID,          \/\/ Set SSID (network name)\n            .password = WIFI_PASS,       \/\/ Set WiFi password\n            .threshold.authmode = WIFI_AUTH_WPA2_PSK,  \/\/ Minimum security protocol\n        },\n    };\n\n    \/\/ Set WiFi to station mode (client mode)\n    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));\n    \n    \/\/ Apply the WiFi configuration\n    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &amp;wifi_config));\n    \n    \/\/ Start the WiFi service\n    ESP_ERROR_CHECK(esp_wifi_start());\n    \n    \/\/ Initiate connection to the configured WiFi network\n    ESP_ERROR_CHECK(esp_wifi_connect());\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"esp-32-modbus-rtu-master\">Wi-Fi \u4e8b\u4ef6\u8655\u7406<\/h2>\n\n\n\n<p>\u6211\u5011\u9700\u8981\u76e3\u807d Wi-Fi \u72c0\u614b\u8b8a\u5316\uff0c\u7279\u5225\u662f\u7372\u5f97 IP \u4f4d\u5740\u5f8c\u555f\u52d5\u767c\u9001\u90f5\u4ef6\u7684\u4efb\u52d9\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">static void wifi_event_handler(void *arg, esp_event_base_t event_base,\n                               int32_t event_id, void *event_data)\n{\n    if (event_base == WIFI_EVENT)\n    {\n        switch (event_id)\n        {\n        case WIFI_EVENT_STA_START:\n            ESP_LOGI(TAG, \"WiFi station started\");\n            break;\n        case WIFI_EVENT_STA_CONNECTED:\n            ESP_LOGI(TAG, \"WiFi connected successfully\");\n            break;\n        case WIFI_EVENT_STA_DISCONNECTED:\n            ESP_LOGI(TAG, \"WiFi disconnected\");\n            break;\n        }\n    }\n    else if (event_base == IP_EVENT)\n    {\n        if (event_id == IP_EVENT_STA_GOT_IP)\n        {\n            ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;\n            ESP_LOGI(TAG, \"Got IP: \" IPSTR, IP2STR(&amp;event-&gt;ip_info.ip));\n\n            \/\/ Create SMTP task once we have an IP address\n            xTaskCreate(smtp_task, \"smtp_task\", SMTP_TASK_STACK_SIZE, NULL, 5, NULL);\n        }\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"base-64-\u7de8\u78bc\u51fd\u6578\">\u5efa\u7acb ESP32 SMTP \u9023\u63a5<\/h2>\n\n\n\n<p>\u6211\u5011\u5c07\u4f7f\u7528 Gmail \u7684 SMTP \u4f3a\u670d\u5668\u9032\u884c\u90f5\u4ef6\u767c\u9001\u3002Gmail \u7684 SMTP \u4f3a\u670d\u5668\u5730\u5740\u70ba smtp.gmail.com\uff0c\u7aef\u53e3\u70ba 465\uff0c\u4f7f\u7528 SSL\/TLS \u5354\u8b70\u9032\u884c\u52a0\u5bc6\u3002<\/p>\n\n\n\n<p>\u5728\u5efa\u7acb\u9023\u63a5\u6642\uff0cESP32 SMTP \u9700\u8981\u652f\u6301 SSL\/TLS\uff0c\u56e0\u6b64\u6211\u5011\u9700\u8981\u4f7f\u7528 esp_tls \u5eab\u3002<\/p>\n\n\n\n<p><strong>Base64 \u7de8\u78bc\u51fd\u6578<\/strong><\/p>\n\n\n\n<p>ESP32 SMTP \u8a8d\u8b49\u904e\u7a0b\u4e2d\u9700\u8981\u5c0d\u90f5\u7bb1\u548c\u5bc6\u78bc\u9032\u884c Base64 \u7de8\u78bc\u3002\u6211\u5011\u5beb\u4e86\u7c21\u55ae\u7684 base64_encode \u51fd\u6578\u4f86\u5b8c\u6210\u9019\u500b\u64cd\u4f5c\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">char* base64_encode(const unsigned char *data, size_t input_length) {\n    const char base64_table[] = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/\";\n    size_t output_length = 4 * ((input_length + 2) \/ 3);\n    char *encoded_data = malloc(output_length + 1);\n    \n    if (encoded_data == NULL) return NULL;\n\n    for (size_t i = 0, j = 0; i &lt; input_length;) {\n        uint32_t octet_a = i &lt; input_length ? data[i++] : 0;\n        uint32_t octet_b = i &lt; input_length ? data[i++] : 0;\n        uint32_t octet_c = i &lt; input_length ? data[i++] : 0;\n        uint32_t triple = (octet_a &lt;&lt; 0x10) + (octet_b &lt;&lt; 0x08) + octet_c;\n\n        encoded_data[j++] = base64_table[(triple &gt;&gt; 3 * 6) &amp; 0x3F];\n        encoded_data[j++] = base64_table[(triple &gt;&gt; 2 * 6) &amp; 0x3F];\n        encoded_data[j++] = base64_table[(triple &gt;&gt; 1 * 6) &amp; 0x3F];\n        encoded_data[j++] = base64_table[(triple &gt;&gt; 0 * 6) &amp; 0x3F];\n    }\n\n    for (size_t i = 0; i &lt; (3 - input_length % 3) % 3; i++) {\n        encoded_data[output_length - 1 - i] = '=';\n    }\n    encoded_data[output_length] = '\\0';\n    return encoded_data;\n}<\/code><\/pre>\n\n\n\n<p><strong>\u767c\u9001\u90f5\u4ef6\u51fd\u6578<\/strong><\/p>\n\n\n\n<p>\u5728\u90f5\u4ef6\u767c\u9001\u904e\u7a0b\u4e2d\uff0c\u6211\u5011\u4f7f\u7528\u4e86 SSL\/TLS \u52a0\u5bc6\u8207 Gmail SMTP \u4f3a\u670d\u5668\u9032\u884c\u901a\u4fe1\uff0c\u4e26\u900f\u904e ESP32 SMTP \u5354\u8b70\u767c\u9001\u90f5\u4ef6\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">void send_email() {\n    ESP_LOGI(TAG, \"Starting SMTP connection, free heap: %d bytes\", esp_get_free_heap_size());\n\n    \/\/ Configure TLS settings for secure SMTP connection\n    esp_tls_cfg_t tls_cfg = {\n        .timeout_ms = SMTP_TIMEOUT * 1000,  \/\/ Connection timeout\n        .crt_bundle_attach = esp_crt_bundle_attach,  \/\/ Use ESP32's certificate bundle\n    };\n\n    \/\/ Initialize TLS structure\n    esp_tls_t *tls = esp_tls_init();\n    if (!tls) {\n        ESP_LOGE(TAG, \"Failed to initialize TLS\");\n        return;\n    }\n\n    \/\/ Establish SSL connection to SMTP server (port 465 for SMTPS)\n    if (!esp_tls_conn_new_sync(SMTP_HOST, strlen(SMTP_HOST), SMTP_PORT, &amp;tls_cfg, tls)) {\n        ESP_LOGE(TAG, \"SSL connection failed\");\n        esp_tls_conn_delete(tls);\n        return;\n    }\n\n    \/\/ SMTP protocol exchange\n    if (!smtp_exchange(tls, NULL, \"220\")) goto cleanup;  \/\/ Wait for server greeting\n    if (!smtp_exchange(tls, \"EHLO ESP32\\r\\n\", \"250\")) goto cleanup;  \/\/ Send EHLO\n    \n    \/\/ Authentication process\n    char *auth_cmd = malloc(128);\n    if (!auth_cmd) goto cleanup;\n    \n    \/\/ Initiate LOGIN authentication\n    if (!smtp_exchange(tls, \"AUTH LOGIN\\r\\n\", \"334\")) goto free_auth;\n    \n    \/\/ Send base64-encoded username\n    char *encoded = base64_encode((const unsigned char *)SENDER_EMAIL, strlen(SENDER_EMAIL));\n    if (!encoded) goto free_auth;\n    snprintf(auth_cmd, 128, \"%s\\r\\n\", encoded);\n    free(encoded);\n    \n    if (!smtp_exchange(tls, auth_cmd, \"334\")) goto free_auth;\n    \n    \/\/ Send base64-encoded password\n    encoded = base64_encode((const unsigned char *)SENDER_PASSWORD, strlen(SENDER_PASSWORD));\n    if (!encoded) goto free_auth;\n    snprintf(auth_cmd, 128, \"%s\\r\\n\", encoded);\n    free(encoded);\n    \n    if (!smtp_exchange(tls, auth_cmd, \"235\")) goto free_auth;  \/\/ Expect authentication success\n    \n    \/\/ Prepare email content\n    char *email_data = malloc(256);\n    if (!email_data) goto free_auth;\n    \n    \/\/ Set sender\n    snprintf(email_data, 256, \"MAIL FROM:&lt;%s&gt;\\r\\n\", SENDER_EMAIL);\n    if (!smtp_exchange(tls, email_data, \"250\")) goto free_all;\n    \n    \/\/ Set recipient\n    snprintf(email_data, 256, \"RCPT TO:&lt;%s&gt;\\r\\n\", RECIPIENT_EMAIL);\n    if (!smtp_exchange(tls, email_data, \"250\")) goto free_all;\n    \n    \/\/ Begin data transmission\n    if (!smtp_exchange(tls, \"DATA\\r\\n\", \"354\")) goto free_all;\n    \n    \/\/ Compose email headers and body\n    snprintf(email_data, 256,\n        \"From: %s\\r\\nTo: %s\\r\\nSubject: ESP32 Test\\r\\n\\r\\n\"\n        \"Hello World!\\r\\n.\\r\\n\",  \/\/ The dot on a line by itself ends the message\n        SENDER_EMAIL, RECIPIENT_EMAIL);\n    \n    \/\/ Send the actual email content\n    smtp_exchange(tls, email_data, \"250\");  \/\/ Expect 250 OK response\n    \nfree_all:\n    free(email_data);\nfree_auth:\n    free(auth_cmd);\ncleanup:\n    \/\/ Gracefully terminate the SMTP session\n    smtp_exchange(tls, \"QUIT\\r\\n\", NULL);\n    esp_tls_conn_delete(tls);\n    ESP_LOGI(TAG, \"SMTP transaction completed\");\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"google-\u61c9\u7528\u5bc6\u78bc\">Google \u61c9\u7528\u5bc6\u78bc<\/h2>\n\n\n\n<p>\u7531\u65bc Google \u5c0d\u65bc\u76f4\u63a5\u4f7f\u7528\u5e33\u6236\u5bc6\u78bc\u9032\u884c\u7b2c\u4e09\u65b9\u61c9\u7528\u767b\u5165\u505a\u4e86\u5b89\u5168\u9650\u5236\uff0c\u5c24\u5176\u662f\u5728\u555f\u7528\u4e86\u300c\u5169\u6b65\u9a5f\u9a57\u8b49\u300d\uff082FA\uff09\u529f\u80fd\u7684\u5e33\u6236\u4e2d\uff0c\u60a8\u5fc5\u9808\u4f7f\u7528&nbsp;<strong>Google \u61c9\u7528\u5bc6\u78bc<\/strong>&nbsp;\u4f86\u9032\u884c\u6b64\u985e\u64cd\u4f5c\u3002\u9019\u662f\u4e00\u7a2e\u5c08\u9580\u70ba\u55ae\u4e00\u61c9\u7528\u6216\u8a2d\u5099\u751f\u6210\u7684\u5bc6\u78bc\uff0c\u53ef\u4ee5\u66ff\u4ee3\u5e33\u6236\u5bc6\u78bc\u9032\u884c\u8eab\u4efd\u9a57\u8b49\u3002<\/p>\n\n\n\n<p><strong>\u6b65\u9a5f 1\uff1a\u555f\u7528 Google \u5169\u6b65\u9a57\u8b49<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u767b\u5165\u5230 Google \u5e33\u6236<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u8a2a\u554f&nbsp;<a class=\"\" href=\"https:\/\/myaccount.google.com\/\" target=\"_blank\" rel=\"noopener\">Google \u5e33\u6236\u9801\u9762<\/a>\uff0c\u4e26\u767b\u5165\u60a8\u7684 Google \u5e33\u6236\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u555f\u7528\u5169\u6b65\u9a57\u8b49<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u5728\u300c\u5b89\u5168\u6027\u300d\u90e8\u5206\uff0c\u555f\u7528\u300c\u5169\u6b65\u9a57\u8b49\u300d\u3002<\/li>\n\n\n\n<li>\u6309\u7167\u63d0\u793a\u5b8c\u6210\u5169\u6b65\u9a57\u8b49\u7684\u8a2d\u7f6e\uff0c\u60a8\u9700\u8981\u7d81\u5b9a\u624b\u6a5f\u6216\u5176\u4ed6\u9a57\u8b49\u65b9\u5f0f\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p><strong>\u6b65\u9a5f 2\uff1a\u751f\u6210\u61c9\u7528\u5bc6\u78bc<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u751f\u6210\u61c9\u7528\u5bc6\u78bc<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u5728\u555f\u7528\u5169\u6b65\u9a57\u8b49\u5f8c\uff0c\u8fd4\u56de\u5230 Google \u5e33\u6236\u7684\u300c\u5b89\u5168\u6027\u300d\u90e8\u5206\uff0c\u627e\u5230&nbsp;<strong>\u300c\u61c9\u7528\u5bc6\u78bc\u300d<\/strong>\u3002<\/li>\n\n\n\n<li>\u9ede\u64ca&nbsp;<strong>\u300c\u751f\u6210\u61c9\u7528\u5bc6\u78bc\u300d<\/strong>&nbsp;\u6309\u9215\u3002<\/li>\n\n\n\n<li>\u9078\u64c7\u300c\u61c9\u7528\u300d\u4e26\u9078\u64c7\u300c\u5176\u4ed6\uff08\u81ea\u5b9a\u7fa9\u540d\u7a31\uff09\u300d\uff0c\u7136\u5f8c\u8f38\u5165\u4f8b\u5982\u300cESP32 SMTP\u300d\u4f5c\u70ba\u540d\u7a31\u3002<\/li>\n\n\n\n<li>\u9ede\u64ca\u751f\u6210\uff0cGoogle \u6703\u986f\u793a\u4e00\u500b 16 \u4f4d\u7684\u61c9\u7528\u5bc6\u78bc\uff08\u4f8b\u5982\uff1a<code>abcd efgh ijkl mnop<\/code>\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>\u8907\u88fd\u61c9\u7528\u5bc6\u78bc<\/strong>\uff1a\n<ul class=\"wp-block-list\">\n<li>\u8907\u88fd\u751f\u6210\u7684\u61c9\u7528\u5bc6\u78bc\uff0c\u9019\u5c31\u662f\u60a8\u5728 ESP32 \u7a0b\u5f0f\u78bc\u4e2d\u9700\u8981\u4f7f\u7528\u7684\u5bc6\u78bc\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<p><strong>\u6b65\u9a5f 3\uff1a\u5728\u7a0b\u5f0f\u78bc\u4e2d\u4f7f\u7528\u61c9\u7528\u5bc6\u78bc<\/strong><\/p>\n\n\n\n<p>\u5728\u7a0b\u5f0f\u78bc\u4e2d\uff0c\u60a8\u5c07\u4e0d\u518d\u4f7f\u7528 Google \u5e33\u6236\u7684\u767b\u5165\u5bc6\u78bc\uff0c\u800c\u662f\u4f7f\u7528\u525b\u525b\u751f\u6210\u7684&nbsp;<strong>\u61c9\u7528\u5bc6\u78bc<\/strong>\u3002\u5728\u4e0b\u9762\u7684\u7a0b\u5f0f\u78bc\u7bc4\u4f8b\u4e2d\uff0c\u60a8\u9700\u8981\u66ff\u63db\u70ba\u60a8\u7684\u61c9\u7528\u5bc6\u78bc\uff0c\u800c\u4e0d\u662f\u539f\u672c\u7684 Google \u5e33\u6236\u5bc6\u78bc\u3002<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">#define SENDER_PASSWORD \"your_app_password\"  \/\/ Use generated app-specific password for Gmail<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"\u5b8c\u6574\u7a0b\u5f0f\u78bc\">\u5b8c\u6574\u7684 ESP32 SMTP \u7a0b\u5f0f\u78bc<\/h2>\n\n\n\n<p>\u6700\u7d42\u7684 ESP32 SMTP \u5b8c\u6574\u7a0b\u5f0f\u78bc\u5982\u4e0b\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp\">#include &lt;string.h>\n#include \"freertos\/FreeRTOS.h\"\n#include \"freertos\/task.h\"\n#include \"esp_wifi.h\"\n#include \"esp_event.h\"\n#include \"esp_log.h\"\n#include \"esp_system.h\"\n#include \"nvs_flash.h\"\n#include \"esp_netif.h\"\n#include \"esp_tls.h\"\n#include \"lwip\/sockets.h\"\n#include \"lwip\/netdb.h\"\n#include \"esp_crt_bundle.h\"\n\n\/\/ Configuration Section ============================================\n#define WIFI_SSID \"your_wifi_ssid\"        \/\/ Wi-Fi SSID\n#define WIFI_PASS \"your_wifi_password\"    \/\/ Wi-Fi password\n#define SMTP_HOST \"smtp.gmail.com\"        \/\/ Gmail SMTP server address\n#define SMTP_PORT 465                     \/\/ SMTP port (SSL)\n#define SENDER_EMAIL \"your_email@gmail.com\"  \/\/ Sender's Gmail address\n#define SENDER_PASSWORD \"your_app_password\"  \/\/ Gmail app password (generated in Google Account)\n#define RECIPIENT_EMAIL \"recipient_email@gmail.com\"  \/\/ Recipient's email address\n#define SMTP_TIMEOUT 10                   \/\/ SMTP timeout in seconds\n#define SMTP_TASK_STACK_SIZE 8192        \/\/ Stack size for SMTP task\n#define MAX_RETRIES 5                    \/\/ Maximum retries for sending email\n\/\/ ===============================================================\n\nstatic const char *TAG = \"SMTP_CLIENT\";\nstatic int s_retry_num = 0;\n\n\/\/ Base64 encoding function\nchar* base64_encode(const unsigned char *data, size_t input_length) {\n    const char base64_table[] = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/\";\n    size_t output_length = 4 * ((input_length + 2) \/ 3);\n    char *encoded_data = malloc(output_length + 1);\n    \n    if (encoded_data == NULL) return NULL;\n\n    for (size_t i = 0, j = 0; i &lt; input_length;) {\n        uint32_t octet_a = i &lt; input_length ? data[i++] : 0;\n        uint32_t octet_b = i &lt; input_length ? data[i++] : 0;\n        uint32_t octet_c = i &lt; input_length ? data[i++] : 0;\n        uint32_t triple = (octet_a &lt;&lt; 0x10) + (octet_b &lt;&lt; 0x08) + octet_c;\n\n        encoded_data[j++] = base64_table[(triple >> 3 * 6) &amp; 0x3F];\n        encoded_data[j++] = base64_table[(triple >> 2 * 6) &amp; 0x3F];\n        encoded_data[j++] = base64_table[(triple >> 1 * 6) &amp; 0x3F];\n        encoded_data[j++] = base64_table[(triple >> 0 * 6) &amp; 0x3F];\n    }\n\n    for (size_t i = 0; i &lt; (3 - input_length % 3) % 3; i++) {\n        encoded_data[output_length - 1 - i] = '=';\n    }\n    encoded_data[output_length] = '\\0';\n    return encoded_data;\n}\n\n\/\/ Function to handle SMTP communication with the server\nbool smtp_exchange(esp_tls_t *tls, const char *send_str, const char *expect_resp) {\n    char *buf = malloc(256);  \/\/ Allocate buffer for response\n    if (!buf) {\n        ESP_LOGE(TAG, \"Failed to allocate buffer\");\n        return false;\n    }\n\n    if (send_str != NULL) {\n        ESP_LOGI(TAG, \"C: %s\", send_str);  \/\/ Log sent command\n        if (esp_tls_conn_write(tls, send_str, strlen(send_str)) &lt; 0) {\n            free(buf);\n            return false;\n        }\n    }\n\n    int len = esp_tls_conn_read(tls, buf, 255);\n    if (len &lt;= 0) {\n        free(buf);\n        return false;\n    }\n    buf[len] = '\\0';\n    ESP_LOGI(TAG, \"S: %.128s\", buf);  \/\/ Log server response (limited to 128 chars)\n\n    bool success = (expect_resp == NULL) || (strstr(buf, expect_resp) != NULL);\n    free(buf);\n    return success;\n}\n\n\/\/ Function to send email\nvoid send_email() {\n    ESP_LOGI(TAG, \"Starting SMTP connection, remaining heap: %d\", esp_get_free_heap_size());\n\n    \/\/ Establish SSL connection\n    esp_tls_cfg_t tls_cfg = {\n        .timeout_ms = SMTP_TIMEOUT * 1000,\n        .crt_bundle_attach = esp_crt_bundle_attach,\n    };\n\n    esp_tls_t *tls = esp_tls_init();\n    if (!tls) {\n        ESP_LOGE(TAG, \"Failed to initialize TLS\");\n        return;\n    }\n\n    \/\/ Connect using SSL (port 465)\n    if (!esp_tls_conn_new_sync(SMTP_HOST, strlen(SMTP_HOST), SMTP_PORT, &amp;tls_cfg, tls)) {\n        ESP_LOGE(TAG, \"SSL connection failed\");\n        esp_tls_conn_delete(tls);\n        return;\n    }\n\n    \/\/ SMTP protocol exchange\n    if (!smtp_exchange(tls, NULL, \"220\")) goto cleanup;\n    if (!smtp_exchange(tls, \"EHLO ESP32\\r\\n\", \"250\")) goto cleanup;\n    \n    \/\/ Authentication process\n    char *auth_cmd = malloc(128);\n    if (!auth_cmd) goto cleanup;\n    \n    if (!smtp_exchange(tls, \"AUTH LOGIN\\r\\n\", \"334\")) goto free_auth;\n    \n    char *encoded = base64_encode((const unsigned char *)SENDER_EMAIL, strlen(SENDER_EMAIL));\n    if (!encoded) goto free_auth;\n    snprintf(auth_cmd, 128, \"%s\\r\\n\", encoded);\n    free(encoded);\n    \n    if (!smtp_exchange(tls, auth_cmd, \"334\")) goto free_auth;\n    \n    encoded = base64_encode((const unsigned char *)SENDER_PASSWORD, strlen(SENDER_PASSWORD));\n    if (!encoded) goto free_auth;\n    snprintf(auth_cmd, 128, \"%s\\r\\n\", encoded);\n    free(encoded);\n    \n    if (!smtp_exchange(tls, auth_cmd, \"235\")) goto free_auth;\n    \n    \/\/ Email content\n    char *email_data = malloc(256);\n    if (!email_data) goto free_auth;\n    \n    snprintf(email_data, 256, \"MAIL FROM:&lt;%s>\\r\\n\", SENDER_EMAIL);\n    if (!smtp_exchange(tls, email_data, \"250\")) goto free_all;\n    \n    snprintf(email_data, 256, \"RCPT TO:&lt;%s>\\r\\n\", RECIPIENT_EMAIL);\n    if (!smtp_exchange(tls, email_data, \"250\")) goto free_all;\n    \n    if (!smtp_exchange(tls, \"DATA\\r\\n\", \"354\")) goto free_all;\n    \n    snprintf(email_data, 256,\n        \"From: %s\\r\\nTo: %s\\r\\nSubject: ESP32 Test\\r\\n\\r\\n\"\n        \"Hello World!\\r\\n.\\r\\n\",\n        SENDER_EMAIL, RECIPIENT_EMAIL);\n    \n    smtp_exchange(tls, email_data, \"250\");\n    \nfree_all:\n    free(email_data);\nfree_auth:\n    free(auth_cmd);\ncleanup:\n    smtp_exchange(tls, \"QUIT\\r\\n\", NULL);\n    esp_tls_conn_delete(tls);\n    ESP_LOGI(TAG, \"SMTP process completed\");\n}\n\n\/\/ SMTP task function\nvoid smtp_task(void *pvParameters) {\n    ESP_LOGI(TAG, \"SMTP task started\");\n\n    \/\/ Send email\n    send_email();\n\n    vTaskDelete(NULL);  \/\/ Task ends\n}\n\n\/\/ Wi-Fi event handler function\nstatic void wifi_event_handler(void *arg, esp_event_base_t event_base,\n                               int32_t event_id, void *event_data)\n{\n    if (event_base == WIFI_EVENT)\n    {\n        switch (event_id)\n        {\n        case WIFI_EVENT_STA_START:\n            ESP_LOGI(TAG, \"WiFi STA started\");\n            break;\n        case WIFI_EVENT_STA_CONNECTED:\n            ESP_LOGI(TAG, \"WiFi connected successfully\");\n            s_retry_num = 0;\n            break;\n        case WIFI_EVENT_STA_DISCONNECTED:\n            if (s_retry_num &lt; MAX_RETRIES)\n            {\n                ESP_LOGI(TAG, \"Attempting to reconnect (%d\/%d)\", s_retry_num + 1, MAX_RETRIES);\n                esp_wifi_connect();\n                s_retry_num++;\n            }\n            else\n            {\n                ESP_LOGE(TAG, \"Connection failed, exceeded maximum retry attempts\");\n            }\n            break;\n        }\n    }\n    else if (event_base == IP_EVENT)\n    {\n        if (event_id == IP_EVENT_STA_GOT_IP)\n        {\n            ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;\n            ESP_LOGI(TAG, \"Got IP: \" IPSTR, IP2STR(&amp;event->ip_info.ip));\n\n            \/\/ Create SMTP task\n            xTaskCreate(smtp_task, \"smtp_task\", SMTP_TASK_STACK_SIZE, NULL, 5, NULL);\n        }\n    }\n}\n\n\/\/ Wi-Fi initialization\nvoid wifi_init_sta() {\n    esp_netif_create_default_wifi_sta();\n\n    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();\n    ESP_ERROR_CHECK(esp_wifi_init(&amp;cfg));\n\n    \/\/ Register event handler\n    ESP_ERROR_CHECK(esp_event_handler_instance_register(\n        WIFI_EVENT, ESP_EVENT_ANY_ID, &amp;wifi_event_handler, NULL, NULL));\n    ESP_ERROR_CHECK(esp_event_handler_instance_register(\n        IP_EVENT, IP_EVENT_STA_GOT_IP, &amp;wifi_event_handler, NULL, NULL));\n\n    wifi_config_t wifi_config = {\n        .sta = {\n            .ssid = WIFI_SSID,\n            .password = WIFI_PASS,\n            .threshold.authmode = WIFI_AUTH_WPA2_PSK,\n        },\n    };\n    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));\n    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &amp;wifi_config));\n    ESP_ERROR_CHECK(esp_wifi_start());\n    ESP_ERROR_CHECK(esp_wifi_connect());\n}\n\nvoid app_main() {\n    ESP_ERROR_CHECK(nvs_flash_init());\n    ESP_ERROR_CHECK(esp_netif_init());\n    ESP_ERROR_CHECK(esp_event_loop_create_default());\n    \n    wifi_init_sta();\n\n    while (1) {\n        vTaskDelay(pdMS_TO_TICKS(1000));\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"\u7de8\u8b6f\u548c\u71d2\u9304\"><strong>\u7de8\u8b6f\u548c\u71d2\u9304<\/strong><\/h2>\n\n\n\n<p>\u5b8c\u6210\u7a0b\u5f0f\u78bc\u5f8c\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528 ESP-IDF \u63d0\u4f9b\u7684\u547d\u4ee4\u9032\u884c\u7de8\u8b6f\u3001\u71d2\u9304\u548c\u76e3\u63a7\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"check-your-inbox\">\u6aa2\u67e5\u4f60\u7684\u6536\u4ef6\u5323<\/h2>\n\n\n\n<p>\u5728\u71d2\u9304\u4e26\u57f7\u884c\u7a0b\u5f0f\u5f8c\uff0c\u8acb<strong>\u6aa2\u67e5\u4f60\u7684\u90f5\u4ef6\u4fe1\u7bb1<\/strong>\uff0c\u78ba\u8a8d\u662f\u5426<strong>\u5df2\u6536\u5230 ESP32 \u88dd\u7f6e\u767c\u9001\u7684\u6e2c\u8a66\u90f5\u4ef6<\/strong>\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"\u7d50\u8ad6\">\u7d50\u8ad6<\/h2>\n\n\n\n<p>\u900f\u904e\u672c\u5c08\u6848\u7684\u5b8c\u6574\u5be6\u4f5c\uff0c\u6211\u5011\u5168\u9762\u638c\u63e1\u4e86\u5728 ESP32 \u5e73\u53f0\u4e0a\u6574\u5408 SMTP \u90f5\u4ef6\u670d\u52d9\u7684\u6838\u5fc3\u6280\u8853\u3002\u9019\u500b ESP32 SMTP \u89e3\u6c7a\u65b9\u6848\u5145\u5206\u767c\u63ee\u4e86\u6676\u7247\u7684Wi-Fi\u548c\u786c\u9ad4\u52a0\u5bc6\u52a0\u901f\u512a\u52e2\uff0c\u63a1\u7528TLS \u5b89\u5168\u5354\u5b9a\u5efa\u7acb\u8207 ESP32 SMTP \u4f3a\u670d\u5668\u7684\u52a0\u5bc6\u9023\u7dda\u3002\u5728\u5be6\u4f5c\u904e\u7a0b\u4e2d\uff0c\u6211\u5011\u7279\u5225\u91dd\u5c0d ESP32 SMTP \u5354\u5b9a\u5806\u758a\u9032\u884c\u4e86\u8a18\u61b6\u9ad4\u7ba1\u7406\u512a\u5316\uff0c\u900f\u904e\u5206\u584a\u8655\u7406\u6280\u8853\u6709\u6548\u89e3\u6c7a\u4e86\u8cc7\u6e90\u53d7\u9650\u74b0\u5883\u4e0b\u767c\u9001\u5927\u578b\u90f5\u4ef6\u7684\u96e3\u984c\uff0c\u540c\u6642\u4fdd\u6301\u4e86\u5b8c\u6574\u7684 SMTP \u5354\u5b9a\u76f8\u5bb9\u6027\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator alignwide has-text-color has-palette-color-1-color has-alpha-channel-opacity has-palette-color-1-background-color has-background is-style-wide\"\/>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>ESP32 SMTP \u6574\u5408 Gmail \u5bc4\u4fe1\u529f\u80fd\u662f IoT \u5c08\u6848\u4e2d\u4e0d\u53ef\u6216\u7f3a\u7684\u5be6\u7528\u6280\u80fd\u4e4b\u4e00\u3002\u672c\u7bc7\u5b8c\u6574\u6559\u5b78\u5c07\u6db5\u84cb  [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3504,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[53,83,2],"tags":[27,21,44,9,11],"class_list":["post-3494","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-esp32","category-featured","category-module","tag-c","tag-ide","tag-programming-language","tag-python","tag-tutorial"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/posts\/3494","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/comments?post=3494"}],"version-history":[{"count":11,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/posts\/3494\/revisions"}],"predecessor-version":[{"id":3508,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/posts\/3494\/revisions\/3508"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/media\/3504"}],"wp:attachment":[{"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/media?parent=3494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/categories?post=3494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/saludpcb.com\/zh\/wp-json\/wp\/v2\/tags?post=3494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}