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日

相关文章

  • 基于layui table返回的值的多级嵌套的解决方法

    基于layui table返回的值的多级嵌套的解决方法攻略 在使用layui table组件时,有时候需要处理多级嵌套的数据结构。本攻略将详细讲解如何解决这个问题,并提供两个示例说明。 解决方法 要解决基于layui table返回的值的多级嵌套问题,可以采用以下步骤: 定义数据结构:首先,需要定义一个合适的数据结构来表示多级嵌套的数据。可以使用对象或数组来…

    other 2023年7月28日
    00
  • 易语言取命令行命令使用讲解

    易语言取命令行命令使用攻略 易语言提供了 GetCommandLine 函数,可以获取程序启动时传入的命令行参数。用户可以根据命令行参数做出不同的处理,这非常适合适用于需要从命令行传入参数的程序。 获取命令行参数 使用 GetCommandLine 函数获取命令行参数,返回值是一个字符串,其格式为: 可执行文件路径 [参数1 参数2 …] 其中,每个参数…

    other 2023年6月26日
    00
  • win7/8.1点击鼠标右键时候很慢迟迟才有反应的解决方法

    下面就是针对“win7/8.1点击鼠标右键时候很慢迟迟才有反应的解决方法”的完整攻略: 1. 原因分析 这个问题可能是由于鼠标右键菜单中的某些项目出现了问题而引起的。或者是由于系统文件出现了问题。因此,我们需要通过逐步排除来确定具体的原因。 2. 解决方法 2.1 检查鼠标右键菜单 第一步是检查鼠标右键菜单中的项目,看看是否有某些项目出现了问题。具体步骤如下…

    other 2023年6月27日
    00
  • httpwatch工具简介及使用技巧

    HttpWatch工具简介及使用技巧攻略 什么是HttpWatch HttpWatch是一个集成于浏览器的http网络流量监控及调试工具,它支持IE和Edge、Chrome和Firefox浏览器。 HttpWatch的功能 HttpWatch可以捕获浏览器在发送http请求过程中的一些重要信息,如请求主机、headers、cookies、请求方法、请求时间等…

    其他 2023年4月16日
    00
  • Spring之从桥接方法到JVM方法调用解读

    Spring之从桥接方法到JVM方法调用解读 前言 本文主要讲解Spring框架中关于桥接方法和JVM方法调用的一些基础知识和实践示例,目的在于让读者更加深入地理解Spring框架的实现原理和机制。 桥接方法 桥接方法是Java编译器为了解决类型参数的类型擦除(Type Erasure)而引入的一种方法,具体来说,当我们在泛型类或泛型接口中声明了一个泛型方法…

    other 2023年6月26日
    00
  • js的基本数据类型与引用数据类型

    下面是关于JavaScript的基本数据类型与引用数据类型的完整攻略,包括定义、区别、使用方法和两个示例说明。 定义 JavaScript中的数据类型分为基本数据类型和引用数据类型。基本数据类型包括:数字、字符串、布尔值、null和undefined。引用数据类型包括:对象、数组和函数。 区别 基本数据类型和引用数据类型的区别在于,基本数据类型的值是简单的数…

    other 2023年5月6日
    00
  • 小米4usb调试怎么打开?miui6进入开发者模式

    下面是“小米4usb调试怎么打开?miui6进入开发者模式”的完整攻略: 打开小米4的USB调试: 步骤一:开启MIUI开发者模式 打开手机设置 向下滑动至底部,点击“关于手机”(有时候叫“关于本机”) 找到“MIUI版本”(MIUI 6及以上版本),然后点击7次 弹出通知,提示“已开启开发者选项” 示例1:如果你的MIUI版本是7及以上,请注意如下操作。在…

    other 2023年6月26日
    00
  • 用批处理/注销脚本清除 存储用户名和密码 列表的代码

    清除存储用户名和密码列表的代码通常会涉及使用批处理脚本或注销脚本。以下是一些步骤和示例来解释如何执行此操作: 步骤一:确定存储用户名和密码的位置 首先,需要找出存储用户名和密码列表的位置。这通常包括Windows凭据管理器或浏览器密码管理器中的存储位置。确定位置后,可以编写代码来删除此位置的文件或更新其内容。 步骤二:编写批处理脚本或注销脚本 有两种方法可以…

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