Linux进程间通信——使用流套接字

下面是Linux进程间通信——使用流套接字的完整攻略:

1. 简介

在Linux中,进程间通信是一项非常重要的功能。进程间通信(IPC)是指在不同进程之间交换数据或信息的机制。Linux提供了多种IPC方式,包括管道、信号量、共享内存、套接字等。本文将重点讲解Linux中使用流套接字进行进程间通信的方法及注意事项。

2. 流套接字的创建

在Linux中,流套接字的创建可以通过socket函数来实现。socket函数的原型如下:

int socket(int domain, int type, int protocol);

其中,domain参数指明了套接字使用的协议族,一般为AF_UNIX(Unix域)或AF_INET(IP域);type参数指明了套接字的类型,一般为 SOCK_STREAM(流套接字)或 SOCK_DGRAM(数据报套接字);protocol参数表示具体的协议,一般为0,表示使用默认协议。下面是创建流套接字的示例代码:

#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>

#define SOCKET_NAME "/tmp/mysocket"

int main(void)
{
    int server_fd;
    int client_fd;
    struct sockaddr_un server_addr;
    struct sockaddr_un client_addr;
    socklen_t client_len;
    ssize_t recv_len;
    char buf[256];

    // 创建套接字
    server_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (server_fd == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 绑定套接字
    memset(&server_addr, 0, sizeof(struct sockaddr_un));
    server_addr.sun_family = AF_UNIX;
    strncpy(server_addr.sun_path, SOCKET_NAME, sizeof(server_addr.sun_path) - 1);
    if (bind(server_fd, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_un)) == -1) {
        perror("bind");
        exit(EXIT_FAILURE);
    }

    // 监听客户端连接请求
    if (listen(server_fd, 5) == -1) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    // 等待客户端连接
    client_fd = accept(server_fd, (struct sockaddr *) &client_addr, &client_len);
    if (client_fd == -1) {
        perror("accept");
        exit(EXIT_FAILURE);
    }

    // 读取客户端发送过来的数据
    recv_len = recv(client_fd, buf, sizeof(buf), 0);
    if (recv_len == -1) {
        perror("recv");
        exit(EXIT_FAILURE);
    }
    buf[recv_len] = '\0';
    printf("Received message: %s\n", buf);

    // 关闭套接字
    close(server_fd);
    close(client_fd);

    // 删除套接字文件
    unlink(SOCKET_NAME);

    return 0;
}

3. 客户端连接

客户端连接流套接字同样可以使用socket函数来实现。为了连接到服务器套接字,客户端需要先创建一个客户端套接字并向服务器套接字发出连接请求。下面是客户端连接流套接字的示例代码:

#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/un.h>

#define SOCKET_NAME "/tmp/mysocket"

int main(void)
{
    int client_fd;
    struct sockaddr_un server_addr;
    ssize_t send_len;
    char buf[256];

    // 创建套接字
    client_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (client_fd == -1) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 连接服务器套接字
    memset(&server_addr, 0, sizeof(struct sockaddr_un));
    server_addr.sun_family = AF_UNIX;
    strncpy(server_addr.sun_path, SOCKET_NAME, sizeof(server_addr.sun_path) - 1);
    if (connect(client_fd, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_un)) == -1) {
        perror("connect");
        exit(EXIT_FAILURE);
    }

    // 向服务器发送数据
    strncpy(buf, "Hello, world!", sizeof(buf));
    send_len = send(client_fd, buf, strlen(buf), 0);
    if (send_len == -1) {
        perror("send");
        exit(EXIT_FAILURE);
    }
    printf("Sent message: %s\n", buf);

    // 关闭套接字
    close(client_fd);

    return 0;
}

4. 流套接字的注意事项

在使用流套接字时,需要特别注意以下事项:

  1. 套接字名必须唯一。Unix域套接字的地址以路径名的形式来表示,因此必须保证路径名在系统中唯一,否则可能会导致套接字创建失败。

  2. 在使用recv函数读取数据时,需要注意其返回值。如果返回0,表示客户端已经关闭连接,此时应该退出程序。如果返回-1,表示读取失败,此时应该检查errno并进行错误处理。

  3. 在使用send函数向服务器发送数据时,需要注意发送的数据长度。如果发送的数据长度超过了套接字缓冲区的大小,可能会导致数据被截断或发送失败。

另外需要注意,Unix域套接字只适用于同一台计算机的进程间通信,如果需要在不同计算机间进行通信,则需要使用IP域套接字。

5. 示例说明

下面是一个使用流套接字进行进程间通信的示例:

# 服务器端(Python)
import socket

def main():
    # 创建套接字
    server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

    # 绑定套接字
    server_socket.bind('/tmp/mysocket')

    # 监听客户端连接请求
    server_socket.listen(5)

    # 等待客户端连接
    client_socket, address = server_socket.accept()
    print('Connected by', address)

    # 读取客户端发送过来的数据
    data = client_socket.recv(1024)
    print('Received message:', data.decode())

    # 关闭套接字
    client_socket.close()
    server_socket.close()

if __name__ == '__main__':
    main()
# 客户端(Python)
import socket

def main():
    # 创建套接字
    client_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

    # 连接服务器套接字
    client_socket.connect('/tmp/mysocket')

    # 向服务器发送数据
    message = 'Hello, world!'.encode()
    client_socket.send(message)
    print('Sent message:', message.decode())

    # 关闭套接字
    client_socket.close()

if __name__ == '__main__':
    main()

以上示例代码中,使用Python语言来创建流套接字,其原理与使用C语言创建流套接字类似,只是语言不同。这两个示例可以作为进一步学习流套接字的参考。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Linux进程间通信——使用流套接字 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Linux利用nc命令监控服务器端口的方法

    下面是详细的”Linux利用nc命令监控服务器端口的方法”攻略: 什么是nc命令 nc命令,全称为netcat命令,是Linux系统中一个非常强大的网络工具。它可以实现TCP/UDP协议的数据传输、端口扫描、端口映射、网络嗅探等功能,是网络安全工程师和服务器运维人员必不可少的工具之一。 监控服务器端口 在Linux服务器中,使用nc命令可以轻松地监控服务器上…

    other 2023年6月27日
    00
  • Spring手动生成web.xml配置文件过程详解

    下面我将详细讲解“Spring手动生成web.xml配置文件过程详解”的完整攻略。 1. 什么是web.xml配置文件 web.xml是Java Web开发中非常重要的配置文件之一,它是Java Web应用程序的部署描述文件,定义了Web应用程序中的Servlet、Filter、Listener等组件及其映射关系和配置。 2. Spring手动生成web.x…

    other 2023年6月25日
    00
  • 1+1>2! 西部数据(西数)SSD+HDD二合一硬盘详尽测试图文讲解

    当然,下面是关于西部数据(SSD+HDD)二合一硬盘的详尽测试图文讲解的完整攻略,包含两个示例说明: 西部数据(SSD+HDD)二合一硬盘详尽测试 1. 硬件介绍 西部数据(SSD+HDD)二合一硬盘是一种结合了固态硬盘(SSD)和机械硬盘(HDD)的创新产品。它的设计旨在提供高速的数据传输和大容量的存储空间。 2. 性能测试 为了评估西部数据(SSD+HD…

    other 2023年10月17日
    00
  • javascript入门基础之私有变量

    JavaScript入门基础之私有变量 在JavaScript中,私有变量是指只能在特定作用域内访问的变量。这些变量对于外部作用域是不可见的,因此可以用于封装和保护数据。本攻略将详细介绍如何创建和使用私有变量。 1. 使用闭包创建私有变量 闭包是一种函数和其相关的引用环境的组合。通过使用闭包,我们可以创建私有变量。下面是一个示例: function crea…

    other 2023年8月9日
    00
  • 操作系统汇编语言之at&t指令

    操作系统汇编语言之AT&T指令 在操作系统开发中,汇编语言是一个不可或缺的工具。在汇编语言中,不同的指令集对于语法的描述方式也不同。AT&T语法是一种常用的汇编语言指令集之一,它主要应用在类Unix操作系统中,如Linux、FreeBSD等。 AT&T语法与Intel语法的区别 常见的汇编语言指令集有两种语法:AT&T语法和I…

    其他 2023年3月28日
    00
  • iOS8.1.1正式版固件下载地址 iOS 8.1.1正式版(12B436/435)固件官方下载大全

    iOS 8.1.1正式版固件下载地址 iOS 8.1.1正式版固件是苹果公司发布的操作系统固件版本,提供了一些修复和改进。以下是获取iOS 8.1.1正式版固件的详细攻略。 步骤一:访问官方网站 首先,你需要访问苹果公司的官方网站以获取iOS 8.1.1正式版固件的下载地址。你可以在以下网址找到官方下载页面:https://www.apple.com/ios…

    other 2023年8月5日
    00
  • easyuicombobox默认选中

    以下是“EasyUI Combobox默认选中”的完整攻略: EasyUI Combobox默认选中 在EasyUI中,我们可以使用Combobox组件来创建下拉列表。以下是如何设置Combobox默认选中的步骤: 1. 设置默认值 可以使用value属性来设置Combobox的默认值。例如,可以使用以下代码: <input class="e…

    other 2023年5月7日
    00
  • 详解Linux环境变量配置全攻略

    详解Linux环境变量配置全攻略 本文将详细讲解如何在Linux系统中配置环境变量。环境变量是指一些特定的变量,用于指示系统或应用程序在执行时需要使用什么样的参数、文件路径、库路径等信息。在Linux中配置环境变量可以方便我们的日常开发和操作。 1. 环境变量的基本概念 1.1 什么是环境变量 环境变量是一些系统级别的参数或变量,用于控制Linux系统中的行…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部