Linux

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > Linux > Linux多进程Socket通信

Linux下实现多进程Socket通信功能的示例代码

作者:酷爱码Linux

Socket通信基于客户端-服务器架构,分为两种主要模式,TCP协议(面向连接)和UDP协议(无连接),下面我们就来看看Linux下实现多进程Socket通信功能具体实现方法吧

一、多进程Socket通信的基本原理

1. Socket通信模型

Socket通信基于客户端-服务器架构,分为以下两种主要模式:

在多进程模型中,服务器通过fork()系统调用为每个客户端连接创建独立的子进程,每个子进程独立处理一个客户端请求,互不干扰。

二、Linux下Socket编程的核心函数

1. 关键函数及其作用

以下函数是实现Socket通信的基础:

函数名功能描述
socket()创建套接字,返回文件描述符。
bind()将套接字绑定到指定的IP地址和端口。
listen()将套接字设为监听状态,等待客户端连接。
accept()接受客户端连接请求,返回新的套接字用于通信。
connect()客户端主动连接服务器。
send()/recv()发送和接收数据。
close()关闭套接字。
fork()创建子进程,用于处理客户端连接。

2. 多进程模型的核心流程

服务器初始化:创建监听套接字,绑定地址和端口,进入监听状态。

客户端连接:服务器通过accept()接受连接,创建子进程处理该连接。

数据交互:子进程与客户端通过send()/recv()进行通信。

资源回收:子进程处理完毕后退出,父进程通过wait()回收资源。

三、多进程Socket通信的实现步骤

1. 服务器端实现

(1)创建监听套接字

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int server_fd, new_socket;
    struct sockaddr_in address;
    int addrlen = sizeof(address);

    // 创建TCP套接字
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd == 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 绑定地址和端口
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;  // 监听所有IP
    address.sin_port = htons(8080);        // 端口8080
    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
        perror("Bind failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    // 监听连接请求
    if (listen(server_fd, 10) < 0) {
        perror("Listen failed");
        close(server_fd);
        exit(EXIT_FAILURE);
    }

    printf("Server is listening on port 8080...\n");

(2)接受连接并创建子进程

    while (1) {
        // 接受客户端连接
        new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen);
        if (new_socket < 0) {
            perror("Accept failed");
            continue;
        }

        // 创建子进程处理连接
        pid_t pid = fork();
        if (pid < 0) {
            perror("Fork failed");
            close(new_socket);
            continue;
        } else if (pid == 0) {
            // 子进程:处理客户端请求
            char buffer[1024] = {0};
            read(new_socket, buffer, 1024);
            printf("Received from client: %s\n", buffer);

            // 发送响应
            const char *response = "Hello from server!";
            write(new_socket, response, strlen(response));
            close(new_socket);
            exit(0);  // 子进程结束
        } else {
            // 父进程:关闭新套接字,继续监听
            close(new_socket);
        }
    }

    // 关闭监听套接字
    close(server_fd);
    return 0;
}

2. 客户端实现

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int sock = 0;
    struct sockaddr_in serv_addr;

    // 创建套接字
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("Socket creation failed");
        exit(EXIT_FAILURE);
    }

    // 设置服务器地址
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(8080);
    serv_addr.sin_addr.s_addr = INADDR_ANY;

    // 连接服务器
    if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("Connection failed");
        close(sock);
        exit(EXIT_FAILURE);
    }

    // 发送请求
    const char *request = "Hello from client!";
    send(sock, request, strlen(request), 0);

    // 接收响应
    char buffer[1024] = {0};
    read(sock, buffer, 1024);
    printf("Server response: %s\n", buffer);

    // 关闭套接字
    close(sock);
    return 0;
}

四、多进程模型的关键注意事项

1. 僵尸进程处理

当子进程结束后,若父进程未调用wait()回收资源,子进程会变为僵尸进程(Zombie)。为避免此问题,可在父进程中注册SIGCHLD信号处理函数:

#include <signal.h>

void sigchld_handler(int sig) {
    int status;
    while (waitpid(-1, &status, WNOHANG) > 0);  // 清理所有僵尸进程
}

// 在服务器主函数中注册信号处理
signal(SIGCHLD, sigchld_handler);

2. 资源泄漏预防

文件描述符关闭:子进程在处理完连接后必须关闭new_socket,父进程也需关闭new_socket以避免资源浪费。

错误处理:对fork()、socket()等函数调用结果进行检查,确保异常情况下的程序健壮性。

3. 性能优化建议

限制最大进程数:通过设置ulimit -n调整系统文件描述符上限,避免过多进程导致系统资源耗尽。

结合I/O多路复用:对于高并发场景,可结合epoll或select实现更高效的事件驱动模型。

五、多进程模型的优缺点分析

1. 优点

2. 缺点

六、总结

多进程Socket通信是Linux环境下实现高并发服务的经典方案,通过fork()为每个客户端创建独立进程,能够有效处理多个客户端请求。然而,开发者需注意僵尸进程、资源泄漏等问题,并根据实际需求选择合适的并发模型(如多线程、事件驱动)。通过本文的代码示例和原理讲解,读者可以快速掌握多进程Socket通信的实现方法,并在此基础上扩展更复杂的应用场景(如文件传输、聊天室等)。

实践建议:

通过不断优化和扩展,多进程Socket通信模型将成为构建高性能网络应用的重要基石。

到此这篇关于Linux下实现多进程Socket通信功能的示例代码的文章就介绍到这了,更多相关Linux多进程Socket通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文