进程间通讯-套接字
2023-12-25 09:50:29
    		介绍
套接字(Socket)是用于进程间通信(IPC)的一种接口技术,它可以协调不同计算机上的进程间的通信,也就是基于网络的通信。同时,它也可以用于同一台计算机上的进程间通信。
 套接字通信的方式有多种。以下是一些关于使用套接字进行进程间通信的基础知识:
-  套接字的类型: - TCP套接字:传输控制协议(Transmission Control Protocol)提供面向连接、可靠的数据传输服务,确保数据包按照发送顺序到达接收端。
- UDP套接字:用户数据报协议(User Datagram Protocol)提供无连接、不可靠但速度快的数据传输服务,不保证数据包的顺序或是否到达。
 
-  套接字的域: - AF_INET:这是最常见的套接字域,用于Internet网络,基于IPv4地址。
- AF_INET6:用于Internet网络,基于IPv6地址。
- AF_UNIX 或 AF_LOCAL:用于同一台机器上的进程间通信,使用文件路径作为地址。
 
-  套接字的创建: 
 在服务器端和客户端都需要创建套接字。这通常涉及到调用socket()系统调用,指定套接字的域、类型和协议。
-  服务器端操作: - 绑定(bind):服务器端需要将其套接字与一个特定的IP地址和端口号关联起来。
- 监听(listen):服务器端设置其套接字进入监听状态,等待客户端的连接请求。
- 接受连接(accept):当有客户端发起连接请求时,服务器端接受这个连接,生成一个新的套接字用于与该客户端通信。
 
-  客户端操作: - 连接(connect):客户端需要指定服务器的IP地址和端口号,然后发起连接请求。
 
-  数据传输: - 发送(send/recv):通过调用 send()和recv()函数,服务器和客户端可以互相发送和接收数据。
- 关闭连接:当通信完成时,双方可以关闭各自的套接字以结束连接。
 
- 发送(send/recv):通过调用 
-  错误处理: 
 在整个过程中,需要适当处理可能出现的错误,如连接失败、发送或接收数据时的错误等。
实现举例
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8080
int main() {
    int server_sock, client_sock;
    struct sockaddr_in server_addr, client_addr;
    socklen_t addr_len = sizeof(struct sockaddr_in);
    char message[100];
    // 创建套接字
    if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }
    // 设置服务器地址信息
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    // 绑定套接字到指定地址
    if (bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("binding failed");
        exit(EXIT_FAILURE);
    }
    // 开始监听连接请求
    if (listen(server_sock, 5) == -1) {
        perror("listening failed");
        exit(EXIT_FAILURE);
    }
    printf("Server is listening on port %d...\n", PORT);
    while (1) {
        // 接受客户端连接请求
        if ((client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addr_len)) == -1) {
            perror("accept failed");
            continue;
        }
        printf("Accepted connection from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
        // 接收客户端发送的消息
        if (recv(client_sock, message, sizeof(message), 0) <= 0) {
            perror("recv failed");
            close(client_sock);
            continue;
        }
        printf("Received message: %s\n", message);
        // 发送回复消息给客户端
        strcpy(message, "Hello from server!");
        if (send(client_sock, message, strlen(message), 0) <= 0) {
            perror("send failed");
            close(client_sock);
            continue;
        }
        printf("Sent reply to client\n");
        // 关闭与客户端的连接
        close(client_sock);
    }
    // 关闭服务器套接字
    close(server_sock);
    return 0;
}
客户端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_IP "127.0.0.1"
#define PORT 8080
int main() {
    int client_sock;
    struct sockaddr_in server_addr;
    char message[100];
    // 创建套接字
    if ((client_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }
    // 设置服务器地址信息
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
        perror("invalid address / address not supported");
        exit(EXIT_FAILURE);
    }
    // 连接到服务器
    if (connect(client_sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("connection failed");
        exit(EXIT_FAILURE);
    }
    printf("Connected to server at %s:%d\n", SERVER_IP, PORT);
    // 发送消息给服务器
    strcpy(message, "Hello from client!");
    if (send(client_sock, message, strlen(message), 0) <= 0) {
        perror("send failed");
        exit(EXIT_FAILURE);
    }
    printf("Sent message to server\n");
    // 接收服务器的回复
    if (recv(client_sock, message, sizeof(message), 0) <= 0) {
        perror("recv failed");
        exit(EXIT_FAILURE);
    }
    printf("Received reply from server: %s\n", message);
    // 关闭套接字
    close(client_sock);
    return 0;
}
示例说明
在这个例子中,服务器在本地主机的8080端口上监听连接请求。客户端连接到服务器,并发送一条消息。服务器接收消息,然后回复一条消息给客户端。最后,客户端接收回复并关闭连接。注意,你需要将SERVER_IP变量设置为你的服务器的实际IP地址(在这个例子中,我们使用的是本地回环地址127.0.0.1)。
总结
套接字通信提供了灵活且强大的机制来进行进程间通信,无论是本地还是网络环境。然而,它也相对复杂,需要处理诸如连接管理、数据流控制、错误处理等问题,所以我们再使用的时候,一定要评估好技术方案,是否有必要通过套接字实现进程通讯。
    			文章来源:https://blog.csdn.net/scy518/article/details/135190925
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
    	本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!