当前位置: 首页 > news >正文

Linux学习之守护进程1

一、相关概念

QQ邮箱关于三种协议的解释:SMTP/IMAP服务

1.SMTP协议

SMTP(​​Simple Mail Transfer Protocol​​,简单邮件传输协议)是一种用于发送电子邮件的互联网标准。它在TCP/IP协议族中,通常使用25端口进行通信。SMTP协议允许邮件发送者和接收者之间的邮件传输,并且可以通过中继器或网关实现不同网络之间的邮件传输。SMTP的一个重要特性是它能够跨越网络传输邮件,这被称为“SMTP邮件中继”。

2.POP3协议

POP3 (Post Office Protocol - Version 3)协议用于支持使用电子邮件客户端获取并删除在服务器上的电子邮件。

POP允许电子邮件客户端下载服务器上的邮件,但是你在电子邮件客户端上的操作(如:移动邮件、标记已读等)不会反馈到服务器上的,比如:你通过电子邮件客户端收取了QQ邮箱中的3封邮件并移动到了其他文件夹,这些移动动作是不会反馈到服务器上的,也就是说,QQ邮箱服务器上的这些邮件是没有同时被移动的。需要特别注意的是,第三方客户端通过POP收取邮件时,也是有可能同步删除服务端邮件。

3.IMAP协议

IMAP(Internet Message Access Protocol,互联网邮件访问协议)是一个应用层协议,用于从本地邮件客户端(如Microsoft Outlook、Outlook Express、Foxmail、Mozilla Thunderbird)访问远程服务器上的邮件。

在IMAP协议上,电子邮件客户端的操作都会反馈到服务器上,你对邮件进行的操作(如:移动邮件、标记已读、删除邮件等)服务器上的邮件也会做相应的动作。也就是说,IMAP 是“双向”的。

4.守护进程

守护进程是后台运行的无终端关联的系统进程,常在启动时启动,提供持续服务,如网络服务、日志记录和定时任务。其特点包括脱离终端、后台运行、持久服务、资源管理和错误处理。创建守护进程涉及重定向文件描述符、创建新会话、改变工作目录等步骤。`ps` 和 `top` 命令用于查看守护进程,前者提供进程快照,后者显示实时资源使用情况。

二、实践

1.telnet登录QQ发送邮件

打开PowerShell,输入下面命令打开telnet

telnet smtp.qq.com 587

如果无法识别telnet,打开控制面板,点击卸载程序,点击左侧的 ​​“启用或关闭 Windows 功能”

找到 ​​“Telnet 客户端”​​,勾选它,然后点击​​确定

等待安装完成,重新打开 ​​PowerShell​​ 或 ​​CMD

按照以下步骤发送邮件

telnet smtp.qq.com 587 (qq邮箱说明:http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=369)

Ehlo qq.com (打招呼)
STARTTLS (开启加密)

auth login (输入登陆命令)

//输入邮箱账号(Base64形式)(回车)
//输入邮箱授权码(Base64形式)(回车)

235 Authentication successful(提示登陆成功)
Mail from:XXXX@qq.com (注意冒号后面别有空格)
250 Ok
Rcpt to:XXX@qq.com (注意冒号后面别有空格)
250 Ok

DATA (输入此命令开始写信)

FROM:XXX@qq.com
TO:XXX@qq.com

SUBJECT:

(空一行)

内容

. (“.”结束)
quit

2.守护进程实现

(1)阿里云守护进程

首先登录QQ邮箱,点击左下方账号与安全中心,点击安全设置,点击生成授权码

在代码中需要用到你的qq邮箱地址(账号@qq.com)和授权码的base64形式,可到此处转换:https://base64.us/

进入在linux系统,输入以下命令,创建.c文件

vim smtp_daemon.c

守护进程代码如下(C语言):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <time.h>
#include <openssl/ssl.h>
#include <openssl/err.h>#define SMTP_SERVER "smtp.qq.com"
#define SMTP_PORT 465               // 使用SSL加密端口
#define EMAIL_FROM "你的qq邮箱地址"
#define EMAIL_PASS "邮箱密码或授权码" // 确认这是最新的授权码
#define EMAIL_TO "实际接收邮箱"SSL_CTX* init_ssl() {SSL_library_init();SSL_load_error_strings();OpenSSL_add_all_algorithms();return SSL_CTX_new(SSLv23_client_method());
}void send_email() {SSL_CTX* ctx = init_ssl();int sockfd;struct hostent *server;struct sockaddr_in serv_addr;char buffer[1024];// 创建socket连接sockfd = socket(AF_INET, SOCK_STREAM, 0);server = gethostbyname(SMTP_SERVER);memset(&serv_addr, 0, sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_port = htons(SMTP_PORT);memcpy(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length);if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {perror("Connection failed");return;}// SSL握手SSL* ssl = SSL_new(ctx);SSL_set_fd(ssl, sockfd);if (SSL_connect(ssl) <= 0) {ERR_print_errors_fp(stderr);return;}// SMTP协议交互SSL_read(ssl, buffer, sizeof(buffer)); // 读取欢迎消息sprintf(buffer, "EHLO localhost\r\n");SSL_write(ssl, buffer, strlen(buffer));SSL_read(ssl, buffer, sizeof(buffer));sprintf(buffer, "AUTH LOGIN\r\n");SSL_write(ssl, buffer, strlen(buffer));SSL_read(ssl, buffer, sizeof(buffer));// 发送base64编码sprintf(buffer, "实际base64编码\r\n");SSL_write(ssl, buffer, strlen(buffer));SSL_read(ssl, buffer, sizeof(buffer));sprintf(buffer, "实际base64编码\r\n");SSL_write(ssl, buffer, strlen(buffer));SSL_read(ssl, buffer, sizeof(buffer));// 设置发件人和收件人sprintf(buffer, "MAIL FROM:<%s>\r\n", EMAIL_FROM);SSL_write(ssl, buffer, strlen(buffer));SSL_read(ssl, buffer, sizeof(buffer));sprintf(buffer, "RCPT TO:<%s>\r\n", EMAIL_TO);SSL_write(ssl, buffer, strlen(buffer));SSL_read(ssl, buffer, sizeof(buffer));// 发送邮件内容sprintf(buffer, "DATA\r\n");SSL_write(ssl, buffer, strlen(buffer));SSL_read(ssl, buffer, sizeof(buffer));time_t now;time(&now);sprintf(buffer, "From: <%s>\r\n""To: <%s>\r\n""Subject: 守护进程状态\r\n""\r\n""守护进程正在运行中....\r\n""当前时间: %s\r\n"".\r\n", EMAIL_FROM, EMAIL_TO, ctime(&now));SSL_write(ssl, buffer, strlen(buffer));SSL_read(ssl, buffer, sizeof(buffer));sprintf(buffer, "QUIT\r\n");SSL_write(ssl, buffer, strlen(buffer));SSL_free(ssl);close(sockfd);SSL_CTX_free(ctx);
}void daemonize() {pid_t pid = fork();if (pid < 0) exit(1);if (pid > 0) exit(0);setsid();chdir("/");umask(0);close(STDIN_FILENO);close(STDOUT_FILENO);close(STDERR_FILENO);
}int main() {daemonize();while(1) {send_email();sleep(60);}return 0;
}

其中邮箱地址以及授权码内容替换为你自己的

编译此文件

gcc smtp_daemon.c -o smtp_daemon -lssl -lcrypto

运行守护程序:

./smtp_daemon

运行结果如下图:

 停止命令:

pkill -f smtp_daemon
(2)树莓派守护进程 

登录树莓派,创建serial_daemon.c文件,代码如下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <signal.h>#define SERIAL_PORT "/dev/serial0"  // 树莓派默认串口设备
#define BAUD_RATE B115200           // 波特率115200
#define MESSAGE "守护进程正在运行中....\r\n"
#define INTERVAL 10                 // 间隔10秒int serial_fd = -1;// 初始化串口
int init_serial() {serial_fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NDELAY);if (serial_fd == -1) {perror("无法打开串口");return -1;}struct termios options;tcgetattr(serial_fd, &options);// 设置波特率cfsetispeed(&options, BAUD_RATE);cfsetospeed(&options, BAUD_RATE);// 8N1配置options.c_cflag &= ~PARENB;options.c_cflag &= ~CSTOPB;options.c_cflag &= ~CSIZE;options.c_cflag |= CS8;// 禁用硬件流控options.c_cflag &= ~CRTSCTS;// 启用接收options.c_cflag |= CREAD | CLOCAL;// 禁用软件流控options.c_iflag &= ~(IXON | IXOFF | IXANY);// 原始输入模式options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);// 原始输出模式options.c_oflag &= ~OPOST;// 设置超时options.c_cc[VMIN] = 0;options.c_cc[VTIME] = 10;tcsetattr(serial_fd, TCSANOW, &options);return 0;
}// 信号处理函数
void signal_handler(int sig) {if (serial_fd != -1) {close(serial_fd);}exit(0);
}// 守护进程化
void daemonize() {pid_t pid = fork();if (pid < 0) {exit(EXIT_FAILURE);}if (pid > 0) {exit(EXIT_SUCCESS); // 父进程退出}// 子进程继续if (setsid() < 0) {exit(EXIT_FAILURE);}// 忽略终端I/O信号signal(SIGTTOU, SIG_IGN);signal(SIGTTIN, SIG_IGN);signal(SIGTSTP, SIG_IGN);signal(SIGHUP, SIG_IGN);// 再次fork确保不是会话组长pid = fork();if (pid < 0) {exit(EXIT_FAILURE);}if (pid > 0) {exit(EXIT_SUCCESS); // 父进程退出}// 设置文件权限掩码umask(0);// 更改工作目录chdir("/");// 关闭所有打开的文件描述符for (int x = sysconf(_SC_OPEN_MAX); x >= 0; x--) {close(x);}
}int main() {// 注册信号处理signal(SIGTERM, signal_handler);signal(SIGINT, signal_handler);// 守护进程化daemonize();// 初始化串口if (init_serial() < 0) {return -1;}// 主循环while (1) {write(serial_fd, MESSAGE, strlen(MESSAGE));sleep(INTERVAL);}close(serial_fd);return 0;
}

 Ctrl+O->Enter-> Ctrl+X保存并退出

编译程序:

gcc serial_daemon.c -o serial_daemon

运行守护进程:

sudo ./serial_daemon

结果如下:

PS:串口配置波特率为115200,接受模式为文本模式,文本编码为UTF-8,不然可能会乱码

 三、总结

本次学习了如何使用telnet登录QQ发送邮件,这一步除了挺多的错,找了一些博客看其中的方法也不行,老是断连。参考文章为Email-FTP-RTSP协议实践研究_rtp邮箱-CSDN博客,还有阿里云上编写一个守护进程程序以及树莓派守护进程,都是问的deepseek,不对的话多问几次就对了。重点是我第一次发现代码可以直接在Putty上粘贴!!!!!(复制之后在Putty端右键点击就粘贴上去了),那我一个一个敲了那么多周算什么???命比苦瓜还苦。。。


http://www.mrgr.cn/news/99285.html

相关文章:

  • 【springsecurity oauth2授权中心】简单案例跑通流程 P1
  • 音视频小白系统入门课-2
  • NestJS-Knife4j
  • 9.策略模式:思考与解读
  • HTTP/1.1 队头堵塞
  • [架构之美]一键服务管理大师:Ubuntu智能服务停止与清理脚本深度解析
  • PostgreSQL 用户资源管理
  • 日语学习-日语知识点小记-构建基础-JLPT-N4阶段(8): - (1)复习一些语法(2)「~ています」
  • Linux系统-cat命令/more命令/less命令
  • 软件工程师中级考试-上午知识点总结(上)
  • LTspice测量SiC MOSFET的C-V特性
  • Linux Wlan-四次握手(eapol)框架流程
  • 本地搭建一个简易版本的 Web3 服务
  • 可穿戴设备待机功耗需降至μA级但需保持实时响应(2万字长文深度解析)
  • python测试框架之pytest
  • Cypress EZ-USB CX3 适配输出imx586相机
  • 【全网最全】23种设计模式思维导图详解 | 含React/Vue/Spring实战案例
  • 数据结构--并查集-高效处理连通性问题
  • python——函数
  • 【C++篇】string类的终章:深浅拷贝 + 模拟实现string类的深度解析(附源码)