linux——网络(服务器的永久不挂——守护进程)


文章目录


目录

文章目录

前言

一、前后台进程

[1. 前台进程 (Foreground Process)](#1. 前台进程 (Foreground Process))

[2. 后台进程 (Background Process)](#2. 后台进程 (Background Process))

[3. 前后台进程的切换](#3. 前后台进程的切换)

[4. 关键命令和操作](#4. 关键命令和操作)

[5. 注意事项](#5. 注意事项)

[6. 信号处理](#6. 信号处理)

二、守护进程

[1. 守护进程的核心特点](#1. 守护进程的核心特点)

[2. 常见守护进程示例](#2. 常见守护进程示例)

3.接口介绍

[1、 fork()](#1、 fork())

[2. setsid()](#2. setsid())

[3. chdir()](#3. chdir())

[4. umask()](#4. umask())

[5. close()](#5. close())

[4. 如何创建守护进程?](#4. 如何创建守护进程?)

步骤解释:

[5. 管理守护进程的工具](#5. 管理守护进程的工具)

[6. 守护进程 vs 前后台进程](#6. 守护进程 vs 前后台进程)

[7. 注意事项](#7. 注意事项)

总结

三、tcp连接机制

[1. 三次握手(Three-Way Handshake)](#1. 三次握手(Three-Way Handshake))

步骤:

为什么需要三次握手?

[2. 四次挥手(Four-Way Handshake)](#2. 四次挥手(Four-Way Handshake))

步骤:

为什么需要四次挥手?

TIME_WAIT状态

[3. 全双工通信(Full-Duplex)](#3. 全双工通信(Full-Duplex))

特点:

示例:

总结

四、网络通信中的序列及反序列

一、序列化的作用

二、反序列化的作用

三、应用场景

四、常见序列化技术

五、安全问题

总结

总结


前言

Linux------网络(tcp)-CSDN博客


一、前后台进程

1. 前台进程 (Foreground Process)

  • 定义:默认情况下,用户在终端启动的进程会占用终端输入/输出,称为前台进程。

  • 特点

    • 进程运行时,终端被"锁定",用户必须等待进程结束才能输入新命令。

    • 进程的输出直接显示在终端,用户可以通过键盘输入与进程交互(如输入参数或终止信号)。

  • 示例

    bash 复制代码
    # 启动一个前台进程(例如 ping 命令)
    ping example.com

2. 后台进程 (Background Process)

  • 定义:进程在后台运行,不占用终端输入/输出,用户可继续使用终端执行其他命令。

  • 特点

    • 终端不会被阻塞,用户可以继续输入命令。

    • 进程的输出仍可能显示在终端(可能干扰当前操作),建议重定向输出到文件。

    • 后台进程的生存期可能与终端会话绑定(若终端关闭,后台进程可能被终止,需使用 nohupdisown 避免)。

  • 启动方式

    bash 复制代码
    # 在命令末尾添加 & 符号
    ping example.com &

3. 前后台进程的切换

  • 将前台进程放到后台

    1. 按下 Ctrl + Z 暂停当前前台进程。

    2. 输入 bg 命令将暂停的进程转为后台运行。

  • 查看后台进程列表

    bash 复制代码
    jobs -l
  • 将后台进程切换到前台

    bash 复制代码
    fg %<job_number>  # 例如 fg %1

4. 关键命令和操作

命令 作用
command & 直接启动后台进程
Ctrl + Z 暂停当前前台进程
bg 将最近暂停的进程转为后台运行
fg %n 将后台进程 n 切换到前台
jobs -l 列出所有后台/暂停的进程及其编号
nohup command & 启动后台进程,终端关闭后仍存活
disown 断开进程与终端的关联

5. 注意事项

  • 输出干扰:后台进程的输出可能混杂在终端中,建议使用输出重定向:

    bash 复制代码
    command > output.log 2>&1 &
  • 终端关闭问题:默认情况下,终端退出时会终止所有关联的后台进程。若需持久化运行:

    • 使用 nohup

      bash 复制代码
      nohup command &
    • 使用 disown

      bash 复制代码
      command &
      disown %1  # 脱离终端关联
    • 使用终端复用工具(如 tmuxscreen)。


6. 信号处理

  • 前台进程可直接接收终端信号(如 Ctrl + C 发送 SIGINTCtrl + Z 发送 SIGTSTP)。

  • 后台进程默认不接收键盘输入信号,但可能收到终端关闭时的 SIGHUP 信号(需通过 nohupdisown 避免)。


通过灵活使用前后台进程,可以高效管理终端任务,尤其适合需要长时间运行或并行操作的情景。

在 Linux 中,**守护进程(Daemon Process)**是一种特殊的后台进程,通常用于长期运行的服务或任务(如 Web 服务器、数据库服务等)。它完全脱离终端控制,独立于用户会话,生命周期与系统运行一致。以下是守护进程的特点及示例:


二、守护进程

1. 守护进程的核心特点

  • 脱离终端:不依赖于任何终端,即使启动它的终端关闭,守护进程依然运行。

  • 无交互界面:不与用户直接交互,通常以静默模式运行。

  • 长期运行:持续驻留内存,提供系统级服务。

  • 独立环境

    • 工作目录通常设置为根目录(/),避免占用挂载点。

    • 文件权限掩码(umask)设为 0,确保文件操作权限可控。

    • 关闭不必要的文件描述符(如标准输入、输出、错误流)。


2. 常见守护进程示例

  • 系统服务

    • sshd:SSH 远程登录服务。

    • nginx/apache:Web 服务器。

    • cron:定时任务调度服务。

  • 自定义守护进程

    • 日志监控脚本。

    • 自动化备份服务。


3.接口介绍

1、 fork()
  • 功能 :用于创建一个新的进程,这个新进程是调用进程(父进程)的副本,被称为子进程。在调用 fork() 之后,父进程和子进程会从 fork() 调用处开始继续执行,通过 fork() 的返回值来区分是父进程还是子进程。
  • 返回值
    • 在父进程中,返回子进程的进程 ID(PID),是一个正整数。
    • 在子进程中,返回 0。
    • 如果出错,返回 -1。
  • 示例代码
cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main() {
    pid_t pid = fork();
    if (pid < 0) {
        perror("fork");
        return 1;
    } else if (pid == 0) {
        // 子进程
        printf("This is child process, PID: %d\n", getpid());
    } else {
        // 父进程
        printf("This is parent process, child PID: %d\n", pid);
    }
    return 0;
}
2. setsid()
  • 功能 :调用 setsid() 的进程会创建一个新的会话,成为新会话的会话首进程,同时也会成为一个新进程组的组长进程,并且脱离原有的控制终端,从而使进程在后台独立运行。
  • 返回值
    • 成功时,返回新会话的会话 ID。
    • 失败时,返回 -1。
  • 示例代码
cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main() {
    pid_t pid = fork();
    if (pid < 0) {
        perror("fork");
        return 1;
    } else if (pid == 0) {
        // 子进程
        pid_t sid = setsid();
        if (sid < 0) {
            perror("setsid");
            return 1;
        }
        printf("New session ID: %d\n", sid);
    }
    return 0;
}
3. chdir()
  • 功能 :用于改变当前进程的工作目录。在创建守护进程时,通常会将工作目录更改为根目录 / 或其他合适的目录,以避免因原工作目录被卸载等情况导致进程出现问题。
  • 返回值
    • 成功时,返回 0。
    • 失败时,返回 -1。
  • 示例代码
cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main() {
    if (chdir("/") == -1) {
        perror("chdir");
        return 1;
    }
    printf("Working directory changed to root.\n");
    return 0;
}
4. umask()
  • 功能:用于设置文件创建掩码,它会影响后续创建文件和目录的默认权限。通过设置合适的掩码,可以确保守护进程创建的文件和目录具有正确的权限。
  • 返回值:返回之前的文件创建掩码。
  • 示例代码
cpp 复制代码
#include <stdio.h>
#include <sys/stat.h>

int main() {
    mode_t old_umask = umask(0);
    printf("Old umask: %o\n", old_umask);
    return 0;
}
5. close()
  • 功能:用于关闭文件描述符。在创建守护进程时,通常会关闭标准输入(文件描述符 0)、标准输出(文件描述符 1)和标准错误输出(文件描述符 2),因为守护进程在后台运行,不需要与终端进行交互。
  • 返回值
    • 成功时,返回 0。
    • 失败时,返回 -1。
  • 示例代码
cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main() {
    close(0);
    close(1);
    close(2);
    printf("Standard file descriptors closed.\n"); // 这行不会有输出,因为标准输出已关闭
    return 0;
}

4. 如何创建守护进程?

以下是一个用 Python 编写的简单守护进程示例,实现每隔 5 秒写入日志的功能:

cpp 复制代码
#pragma once

#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

const std::string nullfile = "/dev/null";

void Daemon(const std::string &cwd = "")
{
    // 1. 忽略其他异常信号
    signal(SIGCLD, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGSTOP, SIG_IGN);

    // 2. 将自己变成独立的会话
    if (fork() > 0)
        exit(0);
    setsid();

    // 3. 更改当前调用进程的工作目录
    if (!cwd.empty())
        chdir(cwd.c_str());

    // 4. 标准输入,标准输出,标准错误重定向至/dev/null
    int fd = open(nullfile.c_str(), O_RDWR);
    if(fd > 0)
    {
        dup2(fd, 0);
        dup2(fd, 1);
        dup2(fd, 2);
        close(fd);
    }
}
步骤解释

代码中有注释


5. 管理守护进程的工具

  • systemd(现代 Linux 系统):

    bash 复制代码
    # 创建服务单元文件(如 /etc/systemd/system/mydaemon.service)
    [Unit]
    Description=My Custom Daemon
    After=network.target
    
    [Service]
    ExecStart=/usr/bin/python3 /path/to/mydaemon.py
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    
    # 启动并启用守护进程
    sudo systemctl start mydaemon
    sudo systemctl enable mydaemon
  • sysvinit (旧系统):通过 init.d 脚本管理。


6. 守护进程 vs 前后台进程

特性 前台进程 后台进程 守护进程
依赖终端 ✔️ 是(锁定终端) ❌ 否(但关联终端) ❌ 完全脱离终端
生命周期 终端关闭则终止 终端关闭可能终止 独立运行,与系统共存亡
典型用途 临时任务 临时后台任务 系统/网络服务
输出交互 直接显示在终端 可能干扰终端 无输出或重定向到日志文件
启动方式 直接运行 command & systemd/nohup/自定义

7. 注意事项

  • 日志管理 :守护进程应记录日志(如通过 syslog 或自定义文件),方便排查问题。

  • 资源泄漏:长期运行的守护进程需注意内存/文件描述符泄漏。

  • 信号处理 :需正确处理 SIGTERMSIGHUP 等信号,实现优雅退出或配置重载。


总结

守护进程是 Linux 系统的"幕后工作者",用于实现核心服务或后台任务。通过脱离终端、配置独立环境,它们能稳定地为系统提供支持。实际开发中,可直接使用 systemd 等工具管理,避免重复造轮子。


三、tcp连接机制

1. 三次握手(Three-Way Handshake)

三次握手用于建立TCP连接,确保双方确认彼此的发送和接收能力正常,并同步初始序列号(Sequence Number)。

步骤:
  1. SYN(同步报文)

    • 客户端向服务器发送 SYN=1 报文,并携带初始序列号 seq=x,表示请求建立连接。
  2. SYN-ACK(同步确认报文)

    • 服务器收到 SYN 后,回复 SYN=1ACK=1 报文,确认客户端的序列号(ack=x+1),并携带自己的初始序列号 seq=y
  3. ACK(确认报文)

    • 客户端确认服务器的 SYN,发送 ACK=1 报文,ack=y+1,连接正式建立。
为什么需要三次握手?
  • 防止历史重复连接的初始化(如旧的延迟 SYN 报文被误认为新请求)。

  • 确保双方确认彼此的发送和接收能力正常。

  • 同步初始序列号,为后续可靠传输奠定基础。


2. 四次挥手(Four-Way Handshake)

四次挥手用于安全释放TCP连接,确保双方数据完全传输完毕,并允许双向独立关闭。

步骤:
  1. FIN(终止报文)

    • 主动关闭方(如客户端)发送 FIN=1 报文,seq=u,表示不再发送数据,但可接收数据。
  2. ACK(确认报文)

    • 被动关闭方(如服务器)回复 ACK=1ack=u+1,确认收到 FIN
  3. FIN(终止报文)

    • 被动关闭方处理完剩余数据后,发送自己的 FIN=1 报文,seq=v
  4. ACK(确认报文)

    • 主动关闭方回复 ACK=1ack=v+1,连接正式关闭。
为什么需要四次挥手?
  • TCP是全双工的,需独立关闭两个方向的数据流。

  • 被动关闭方可能需要时间处理未发送完的数据,延迟发送自己的 FIN

TIME_WAIT状态

主动关闭方在发送最后一个 ACK 后会进入 TIME_WAIT 状态(持续2MSL,即最大报文生存时间),确保:

  • 被动关闭方收到最终的 ACK

  • 防止旧连接的延迟报文干扰新连接。


3. 全双工通信(Full-Duplex)

TCP连接是全双工 的,即通信双方可同时、独立地发送和接收数据,互不影响。

特点:
  • 双向传输:两端均有独立的发送和接收缓冲区。

  • 并行性:发送数据无需等待对方响应(如:上传文件时仍可接收消息)。

  • 流量控制:通过滑动窗口机制,独立管理每个方向的数据流速率。

示例
  • 视频通话:双方同时传输音视频数据。

  • HTTP/1.1 Keep-Alive:浏览器和服务器复用同一连接处理多个请求。


总结

机制 目的 关键点
三次握手 建立可靠的双向连接 防历史连接、同步序列号、确认双方能力
四次挥手 安全释放双向连接 独立关闭、处理残留数据、TIME_WAIT防报文丢失
全双工通信 支持双向同时数据传输 独立缓冲区、滑动窗口控制、高效并行通信

这些机制共同保障了TCP的可靠性、有序性和高效性,成为互联网数据传输的基石。


四、网络通信中的序列及反序列

一、序列化的作用

  1. 将数据转换为通用格式

    • 在发送端,程序中的复杂数据结构(如对象、数组、字典等)无法直接在网络中传输,必须转换成一种标准化的字节流(如 JSON、XML、Protocol Buffers、二进制等)。

    • 例如 :一个 Python 字典 {"name": "Alice", "age": 30} 会被序列化为 JSON 字符串 {"name":"Alice","age":30} 或二进制格式。

  2. 跨平台/跨语言兼容性

    • 不同编程语言(如 Python、Java、C++)对数据结构的实现差异较大,序列化后的通用格式可被任何语言解析,确保异构系统间的通信。
  3. 压缩与优化

    • 序列化时可通过算法(如 Protocol Buffers、MessagePack)压缩数据体积,减少网络带宽消耗,提升传输效率。
  4. 持久化存储

    • 序列化后的数据可保存到文件或数据库(如 Redis 缓存对象),便于后续恢复或传输。

二、反序列化的作用

  1. 重建原始数据结构

    • 接收端将收到的字节流还原为程序可操作的原生数据结构。例如将 JSON 字符串反序列化为 Java 对象或 Python 字典。
  2. 数据校验与安全

    • 反序列化时可以对数据进行格式校验(如 JSON Schema),防止恶意构造的数据攻击(如反序列化漏洞)。
  3. 支持复杂类型

    • 处理嵌套对象、日期、枚举等特殊类型,确保数据完整性(例如将 JSON 中的字符串 "2023-10-01" 转换为 Date 对象)。

三、应用场景

  1. 网络通信协议

    • HTTP API:客户端发送 JSON/XML 请求,服务端反序列化为对象处理。

    • RPC(远程过程调用):如 gRPC 使用 Protocol Buffers 序列化数据。

    • 消息队列:Kafka、RabbitMQ 传输的消息需序列化。

  2. 分布式系统

    • 微服务间通过序列化传递数据(如 Dubbo 使用 Hessian 序列化)。
  3. 缓存与存储

    • Redis 存储对象时需序列化为字符串或二进制。

四、常见序列化技术

格式/协议 特点
JSON 人类可读、跨语言支持,但冗余较多,性能较低。
XML 标签化结构,支持复杂数据,但体积大。
Protocol Buffers 二进制、高效压缩,需预定义 Schema(.proto 文件),适合高性能场景。
MessagePack 二进制,比 JSON 更紧凑,无需 Schema。
Avro 动态 Schema 支持,常用于大数据系统(如 Hadoop)。

五、安全问题

  • 反序列化漏洞 :攻击者构造恶意序列化数据,触发远程代码执行(如 Java 的 ObjectInputStream 漏洞)。

  • 防御措施:使用安全协议(如 TLS)、校验数据签名、限制反序列化类白名单。


总结

序列化和反序列化是网络通信的"翻译官",解决了数据在异构环境中的标准化传输语义一致性问题,是分布式系统、微服务、实时通信等技术的基础支撑。


总结

在 Linux 中,**守护进程(Daemon Process)**是一种特殊的后台进程,通常用于长期运行的服务或任务(如 Web 服务器、数据库服务等)。它完全脱离终端控制,独立于用户会话,生命周期与系统运行一致。

机制 目的 关键点
三次握手 建立可靠的双向连接 防历史连接、同步序列号、确认双方能力
四次挥手 安全释放双向连接 独立关闭、处理残留数据、TIME_WAIT防报文丢失
全双工通信 支持双向同时数据传输 独立缓冲区、滑动窗口控制、高效并行通信

这些机制共同保障了TCP的可靠性、有序性和高效性,成为互联网数据传输的基石。

序列化和反序列化是网络通信的"翻译官",解决了数据在异构环境中的标准化传输语义一致性问题,是分布式系统、微服务、实时通信等技术的基础支撑。

相关推荐
丢丢丢丢丢丢~8 分钟前
在 Debian/Ubuntu 系统上,永久固定网口的IP地址
运维·ubuntu·debian
fareast_mzh8 分钟前
Running a Snowflake on Debian 11
linux·服务器·debian
zhangzhangkeji20 分钟前
(9) 上:学习与验证 linux 里的 epoll 对象里的 EPOLLIN、 EPOLLHUP 与 EPOLLRDHUP 的不同
linux·网络·epoll 标志
我们的五年24 分钟前
【Linux网络编程】:URL(encode),HTTP协议,telnet工具
linux·服务器·网络·c++·网络协议·http
biubiubiu070641 分钟前
关于maven
java·linux·maven
苏-言42 分钟前
Docker深度解析:部署 SpringBoot 项目
运维·docker·容器
狮歌~资深攻城狮1 小时前
Elasticsearch 就业形势
运维·jenkins
Roadinforest2 小时前
结合 vim-plug 安装并使用 Gruvbox 主题教程
linux·编辑器·vim
Roadinforest2 小时前
vim-plug的自动安装与基本使用介绍
linux·编辑器·vim
Web极客码2 小时前
应对现代电子商务的网络威胁—全面安全战略
服务器·恶意软件·实时监控