在阿里云和樹莓派上編寫一個守護進程程序

目錄

一、阿里云郵件守護進程

1. 安裝必要庫

2. 創建郵件發送腳本?mail_daemon.py

3. 設置后臺運行

二、樹莓派串口守護進程

1. 啟用樹莓派串口

2. 安裝依賴庫

3. 創建串口輸出腳本?serial_daemon.py

4. 設置開機自啟

5. 使用串口助手接收


一、阿里云郵件守護進程

1. 安裝必要庫
pip3 install smtplib email schedule
2. 創建郵件發送腳本?mail_daemon.py
import smtplib
import schedule
import time
from email.mime.text import MIMEText
from email.header import Header# 配置信息(替換為你的信息)
SMTP_SERVER = 'smtp.163.com'        # 例如163郵箱
SMTP_PORT = 465                     # SSL端口
SENDER_EMAIL = 'your_email@163.com'
SENDER_PASSWORD = 'your_password'   # 或授權碼
RECEIVER_EMAIL = 'receiver@example.com'def send_email():message = MIMEText('守護進程正在運行中....', 'plain', 'utf-8')message['From'] = Header(SENDER_EMAIL)message['To'] = Header(RECEIVER_EMAIL)message['Subject'] = Header('阿里云守護進程狀態')try:smtp = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT)smtp.login(SENDER_EMAIL, SENDER_PASSWORD)smtp.sendmail(SENDER_EMAIL, [RECEIVER_EMAIL], message.as_string())smtp.quit()print("郵件發送成功")except Exception as e:print(f"郵件發送失敗: {str(e)}")def job():send_email()if __name__ == '__main__':schedule.every(1).minutes.do(job)while True:schedule.run_pending()time.sleep(1)
3. 設置后臺運行
nohup python3 mail_daemon.py > /dev/null 2>&1 &

二、樹莓派串口守護進程

1. 啟用樹莓派串口
# 禁用藍牙占用串口
sudo raspi-config
# 選擇 Interfacing Options -> Serial -> No 關閉登錄shell -> Yes 啟用硬件串口
sudo reboot# 驗證串口
ls -l /dev/serial*  # 應顯示 /dev/serial0 -> ttyAMA0
2. 安裝依賴庫
sudo apt-get install python3-serial
3. 創建串口輸出腳本?serial_daemon.py
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <openssl/ssl.h>
#include <openssl/err.h>#define SMTP_SERVER "smtp.qq.com"
#define SMTP_PORT 465
#define SENDER_EMAIL "your_email@qq.com"
#define SENDER_PASSWORD "your_auth_code"
#define RECEIVER_EMAIL "receiver@example.com"
#define LOG_FILE "/tmp/daemon_email.log"// 守護進程初始化
void daemonize() {pid_t pid = fork();if (pid < 0) {perror("First fork failed");exit(EXIT_FAILURE);}if (pid > 0) exit(EXIT_SUCCESS); // 父進程退出// 創建新會話if (setsid() < 0) {perror("setsid failed");exit(EXIT_FAILURE);}// 第二次forkpid = fork();if (pid < 0) {perror("Second fork failed");exit(EXIT_FAILURE);}if (pid > 0) exit(EXIT_SUCCESS);// 設置文件權限掩碼umask(0);// 改變工作目錄chdir("/");// 關閉標準文件描述符close(STDIN_FILENO);close(STDOUT_FILENO);close(STDERR_FILENO);
}// 日志記錄函數
void log_message(const char* message) {time_t now;time(&now);char* dt = ctime(&now);dt[strlen(dt)-1] = '\0'; // 去除換行符FILE* log_file = fopen(LOG_FILE, "a");if (log_file) {fprintf(log_file, "%s - %s\n", dt, message);fclose(log_file);}
}// Base64編碼(簡化版,實際應使用完整實現)
char* base64_encode(const char* input) {BIO *bio, *b64;BUF_MEM *bufferPtr;b64 = BIO_new(BIO_f_base64());bio = BIO_new(BIO_s_mem());bio = BIO_push(b64, bio);BIO_write(bio, input, strlen(input));BIO_flush(bio);BIO_get_mem_ptr(bio, &bufferPtr);char* output = (char*)malloc(bufferPtr->length + 1);memcpy(output, bufferPtr->data, bufferPtr->length);output[bufferPtr->length] = '\0';BIO_free_all(bio);return output;
}// 發送SMTP命令并檢查響應
int smtp_command(SSL* ssl, const char* cmd, const char* expect_code, int log) {char buffer[1024];if (cmd) SSL_write(ssl, cmd, strlen(cmd));SSL_read(ssl, buffer, sizeof(buffer));if (log) {log_message(buffer);}return (strstr(buffer, expect_code) != NULL);
}// 發送郵件函數
int send_email() {struct sockaddr_in addr;int sock;SSL_CTX* ctx;SSL* ssl;// 初始化OpenSSLSSL_library_init();OpenSSL_add_all_algorithms();SSL_load_error_strings();ctx = SSL_CTX_new(SSLv23_client_method());// 創建socketsock = socket(AF_INET, SOCK_STREAM, 0);addr.sin_family = AF_INET;addr.sin_port = htons(SMTP_PORT);inet_pton(AF_INET, SMTP_SERVER, &addr.sin_addr);// 連接服務器if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) {log_message("Connection failed");return -1;}// 創建SSL連接ssl = SSL_new(ctx);SSL_set_fd(ssl, sock);if (SSL_connect(ssl) <= 0) {log_message("SSL connection failed");return -1;}// SMTP協議交互if (!smtp_command(ssl, NULL, "220", 1)) goto error; // 讀取歡迎消息if (!smtp_command(ssl, "EHLO localhost\r\n", "250", 1)) goto error;// 認證char auth_cmd[256];sprintf(auth_cmd, "AUTH LOGIN\r\n");if (!smtp_command(ssl, auth_cmd, "334", 1)) goto error;char* encoded_user = base64_encode(SENDER_EMAIL);sprintf(auth_cmd, "%s\r\n", encoded_user);if (!smtp_command(ssl, auth_cmd, "334", 1)) goto error;free(encoded_user);char* encoded_pass = base64_encode(SENDER_PASSWORD);sprintf(auth_cmd, "%s\r\n", encoded_pass);if (!smtp_command(ssl, auth_cmd, "235", 1)) goto error;free(encoded_pass);// 構造郵件sprintf(auth_cmd, "MAIL FROM:<%s>\r\n", SENDER_EMAIL);if (!smtp_command(ssl, auth_cmd, "250", 1)) goto error;sprintf(auth_cmd, "RCPT TO:<%s>\r\n", RECEIVER_EMAIL);if (!smtp_command(ssl, auth_cmd, "250", 1)) goto error;if (!smtp_command(ssl, "DATA\r\n", "354", 1)) goto error;const char* email_body = "From: \"Daemon\" <" SENDER_EMAIL ">\r\n""To: " RECEIVER_EMAIL "\r\n""Subject: Status Report\r\n\r\n""Daemon is running...\r\n.\r\n";SSL_write(ssl, email_body, strlen(email_body));if (!smtp_command(ssl, NULL, "250", 1)) goto error;// 退出smtp_command(ssl, "QUIT\r\n", "221", 1);SSL_free(ssl);close(sock);SSL_CTX_free(ctx);return 0;error:SSL_free(ssl);close(sock);SSL_CTX_free(ctx);return -1;
}int main() {daemonize();log_message("Daemon started");while(1) {if (send_email() == 0) {log_message("Email sent successfully");} else {log_message("Failed to send email");}sleep(60); // 每分鐘發送一次}return 0;
}

4. 設置開機自啟

創建?/etc/systemd/system/serial_daemon.service

[Unit]
Description=Serial Daemon Service[Service]
ExecStart=/usr/bin/python3 /home/pi/serial_daemon.py
Restart=always
User=pi[Install]
WantedBy=multi-user.target
5. 使用串口助手接收
sudo apt-get install minicom
minicom -b 115200 -o -D /dev/serial0

實驗結果:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/79730.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79730.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/79730.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python----深度學習(全連接與鏈式求導法則)

一、機器學習和深度學習的區別 機器學習&#xff1a;利用計算機、概率論、統計學等知識&#xff0c;輸入數據&#xff0c;讓計算機學會新知 識。機器學習的過程&#xff0c;就是訓練數據去優化目標函數。 深度學習&#xff1a;是一種特殊的機器學習&#xff0c;具有強大的能力和…

Python爬蟲實戰:獲取網易新聞數據

一、引言 隨著互聯網的飛速發展,網絡上蘊含著海量的信息資源。新聞數據作為其中的重要組成部分,對于輿情分析、市場研究、信息傳播等多個領域具有重要價值。網易新聞作為國內知名的新聞平臺,擁有豐富多樣的新聞內容。使用 Python 的 Scrapy 框架進行網易新聞數據的爬取,可…

matlab論文圖一的地形區域圖的球形展示Version_1

matlab論文圖一的地形區域圖的球形展示Version_1 圖片 此圖來源于&#xff1a; ![Jieqiong Zhou, Ziyin Wu, Dineng Zhao, Weibing Guan, Chao Zhu, Burg Flemming, Giant sand waves on the Taiwan Banks, southern Taiwan Strait: Distribution, morphometric relationship…

藍橋杯:連連看

本題大意要我們在一個給定的nxm的矩形數組中找出符合條件的格子 條件如下&#xff1a; 1.數值相同 2.兩個橫坐標和縱坐標的差值相等&#xff08;由此可得是一個對角線上的格子&#xff09; 那么根據以上條件我們可以用HashMap來解決這個問題&#xff0c;統計對角線上數值相同…

PHP中的ReflectionClass講解【詳細版】

快餐&#xff1a; ReflectionClass精簡版 在PHP中&#xff0c;ReflectionClass是一個功能強大的反射類&#xff0c;它就像是一個類的“X光透視鏡”&#xff0c;能讓我們在程序運行時深入了解類的內部結構和各種細節。 一、反射類的基本概念和重要性 反射是指在程序運行期間獲…

微信小程序中,將搜索組件獲取的值傳遞給父頁面(如 index 頁面)可以通過 自定義事件 或 頁面引用 實現

將搜索組件獲取的值傳遞給父頁面&#xff08;如 index 頁面&#xff09;可以通過 自定義事件 或 頁面引用 實現 方法 1&#xff1a;自定義事件&#xff08;推薦&#xff09; 步驟 1&#xff1a;搜索組件內觸發事件 在搜索組件的 JS 中&#xff0c;當獲取到搜索值時&#xff0c…

Django 實現服務器主動給客戶端發送消息的幾種常見方式及其區別

Django Channels 原理 &#xff1a;Django Channels 是 Django 的一個擴展&#xff0c;它通過使用 WebSockets 等協議來處理長連接&#xff0c;使服務器能夠與客戶端建立持久連接&#xff0c;從而實現雙向通信。一旦連接建立&#xff0c;服務器可以隨時主動向客戶端發送消息。…

PHP最新好看UI個人引導頁網頁源碼

PHP最新好看UI個人引導頁網頁源碼 采用PHP、HTML、CSS及JavaScript等前端技術&#xff0c;構建了一個既美觀又實用的個人主頁解決方案。 源碼設計初衷在于提供一個高度可定制、跨平臺兼容的模板&#xff0c;讓用戶無需深厚的編程基礎&#xff0c;即可快速搭建出專業且富有創意的…

HarmonyOS學習 實驗九:@State和@Prop裝飾器的使用方法

HarmonyOS應用開發&#xff1a;父子組件狀態管理實驗報告 引言 在HarmonyOS應用開發領域&#xff0c;組件之間的狀態管理是一個至關重要的概念。通過有效的狀態管理&#xff0c;我們可以確保應用的數據流動清晰、可預測&#xff0c;從而提升應用的穩定性和可維護性。本次實驗…

12.第二階段x64游戲實戰-遠程調試

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 本次游戲沒法給 內容參考于&#xff1a;微塵網絡安全 上一個內容&#xff1a;11.第二階段x64游戲實戰-框架代碼細節優化 本次寫的內容是關于調試、排錯相關的…

c++基礎三

1.繼承 繼承表示,子類可以獲取父類的屬性和方法,然后可以寫子類獨有的屬性和方法,或者修改父類的方法。類可以繼承父類的公共成員(public),但不能繼承私有成員(private),私有成員只能在父類內部訪問。 1.1 案例一單繼承 #include <iostream>using namespace …

JSON學習筆記

文章目錄 1. JSON是什么2. JSON的特點與結構3. JSON的使用4. JSON文件讀取 1. JSON是什么 JSON&#xff08;JavaScript Object Notation&#xff0c;JavaScript對象表示法&#xff09;是一種輕量級的數據交換格式&#xff0c;易于人閱讀和編寫&#xff0c;同時也易于機器解析和…

王牌學院,25西電通信工程學院(考研錄取情況)

1、通信工程學院各個方向 2、通信工程學院近三年復試分數線對比 學長、學姐分析 由表可看出&#xff1a; 1、信息與通信工程25年相較于24年上升5分、軍隊指揮學25年相較于24年上升30分 2、新一代電子信息技術&#xff08;專碩&#xff09;25年相較于24年下降25分、通信工程&…

WPF依賴注入IHostApplicationLifetime關閉程序

WPF依賴注入IHostApplicationLifetime關閉程序 使用Application.Current.Shutdown();退出會報異常 應該使用 app.Dispatcher.InvokeShutdown(); Application.Current.Shutdown();app.Dispatcher.InvokeShutdown();static App app new();[STAThread]public static void Main(…

Jenkins 代理自動化-dotnet程序

兩種方式 容器部署 本地部署 容器部署 可自動實現&#xff0c;服務器重啟&#xff0c;容器自動運行 主要將dockerfile 寫好 本地部署 1.服務器重啟自動運行代理 參考下面的鏈接&#xff0c;只是把程序換成 java程序&#xff0c;提前確認好需要的jdk版本 Ubuntu20.04 設置開機…

從Archery到NineData:積加科技驅動數據庫研發效能與數據安全雙升級

積加科技作為國內領先的企業級數字化解決方案服務商&#xff0c;依托自研的 A4X 數字化平臺&#xff08;https://a4x.io/&#xff09;&#xff0c;專注于為全球范圍內的視覺物聯網&#xff08;IoT&#xff09;設備提供 PaaS/SaaS 服務。致力于運用 AI 技術賦能物聯網世界的各類…

SpringBoot整合Logback日志框架深度實踐

一、依賴與默認集成機制 SpringBoot從2.x版本開始默認集成Logback日志框架,無需手動添加額外依賴。當項目引入spring-boot-starter-web時,該組件已包含spring-boot-starter-logging,其底層實現基于Logback+SLF4J組合。這種設計使得開發者只需關注業務日志的輸出規則,無需處…

自由學習記錄(56)

從貼圖空間&#xff08;texture space&#xff09;將值還原到切線空間&#xff08;tangent space&#xff09;向量 tangentNormal.xy (packedNormal.xy * 2 - 1) * _BumpScale; 背后的知識點&#xff1a;法線貼圖中的 RGB 是在 0~1 范圍內編碼的向量 所以貼圖法線是怎么“壓…

【mysql】mysql疑難問題:實際場景解釋什么是排它鎖 當前讀 快照讀

注&#xff1a; 理解本文 前置需要掌握的基礎知識&#xff1a;事務隔離、鎖的概念、并發知識&#xff1b; 事務隔離 尤其是事務延伸問題 是個重難點&#xff0c;絕非八股文那幾句話就能說完的&#xff0c;在實際場景中&#xff0c;分析起來有一定難度 author: csdn博主 孟秋與你…

Python:使用web框架Flask搭建網站

Date: 2025.04.19 20:30:43 author: lijianzhan Flask 是一個輕量級的 Python Web 開發框架&#xff0c;以簡潔靈活著稱&#xff0c;適合快速構建中小型 Web 應用或 API 服務。以下是 Flask 的核心概念、使用方法和實踐指南 Flask 的核心特點&#xff1a; 輕量級 核心代碼僅約…