4.35、本地套接字

本地套接字用于无关系的进程间通信,其流程类似于TCP网络套接字,涉及创建、绑定、监听、接受和通信等步骤。服务端创建监听套接字,绑定并监听特定路径的套接字文件,客户端则连接该文件进行通信。文中给出了服务端和客户端的C++代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.本地套接字的介绍

本地套接字的作用:本地的进程间通信

  • 有关系的进程间的通信
  • 没有关系的进程间的通信
  • 本地套接字实现流程和网络套接字类似,一般呢采用TCP的通信流程。
  • ip地址的类型(我们应该使用sockaddr_un)
    在这里插入图片描述

2.本地套接字通信的流程

// 头文件: sys/un.h
#define UNIX_PATH_MAX 108
struct sockaddr_un {
	sa_family_t sun_family; // 地址族协议 af_local
	char sun_path[UNIX_PATH_MAX]; // 套接字文件的路径, 这是一个伪文件, 大小永远=0
};


// 本地套接字通信的流程 - tcp
// 删除文件
	unlink("server.sock")
	unlink("client.sock")
	
// 服务器端
1. 创建监听的套接字
	int lfd = socket(AF_UNIX/AF_LOCAL, SOCK_STREAM, 0);
2. 监听的套接字绑定本地的套接字文件 -> server端
	struct sockaddr_un addr;
	// 绑定成功之后,指定的sun_path中的套接字文件会自动生成。
	bind(lfd, addr, len);
3. 监听
	listen(lfd, 100);
4. 等待并接受连接请求
	struct sockaddr_un cliaddr;
	int cfd = accept(lfd, &cliaddr, len);
5. 通信
	接收数据:read/recv
	发送数据:write/send
6. 关闭连接
	close();
	// 客户端的流程


1. 创建通信的套接字
	int fd = socket(AF_UNIX/AF_LOCAL, SOCK_STREAM, 0);
2. 监听的套接字绑定本地的IP 端口
	struct sockaddr_un addr;
	// 绑定成功之后,指定的sun_path中的套接字文件会自动生成。
	bind(lfd, addr, len);
3. 连接服务器
	struct sockaddr_un serveraddr;
	connect(fd, &serveraddr, sizeof(serveraddr));
4. 通信
	接收数据:read/recv
	发送数据:write/send
5. 关闭连接
	close();

3.本地套接字代码编写

①服务端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/un.h>

using namespace std;

int main() {

    // 删除文件
    unlink("server.sock");

    // 客户端创建监听描述符
    int lfd = socket(AF_LOCAL, SOCK_STREAM, 0);


    // 绑定本地的套字节文件
    sockaddr_un server_addr;
    server_addr.sun_family = AF_LOCAL;
    strcpy(server_addr.sun_path, "server.sock");
    bind(lfd, (sockaddr *)&server_addr, sizeof(server_addr));


    // 监听客户端是否连接
    listen(lfd, 8);


    // 接收获取客户端的信息
    sockaddr_un client_addr;
    socklen_t len = sizeof(client_addr);
    int cfd = accept(lfd, (sockaddr *)&client_addr, &len);


    // 输出客户端的套字节
    printf("client sock filename: %s\n", client_addr.sun_path);

    // 进行通信
    char recvBuf[128];
    while (1) {

        int len = recv(cfd, recvBuf, sizeof(recvBuf), 0);

        if (len == -1) {
            perror("recv");
            exit(-1);
        } else if (len == 0) {
            cout << "client closed..." << endl;
            break;
        } else if (len > 0) {
            printf("I am server, data: %s\n", recvBuf);
            send(cfd, recvBuf, strlen(recvBuf) + 1, 0);
        }

    }

    return 0;
}

②客户端

#include <iostream>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/un.h>

using namespace std;

int main() {

    // 删除文件
    unlink("client.sock");

    // 创建通信的文件描述符
    int cfd = socket(AF_LOCAL, SOCK_STREAM, 0);

    // 绑定本地套接字文件
    sockaddr_un client_addr;
    client_addr.sun_family = AF_LOCAL;
    strcpy(client_addr.sun_path, "client.sock");
    bind(cfd, (sockaddr *)&client_addr, sizeof(client_addr));

    // 连接服务器
    sockaddr_un server_addr;
    server_addr.sun_family = AF_LOCAL;
    strcpy(server_addr.sun_path, "server.sock");
    // 向服务端发起连接
    connect(cfd, (sockaddr *)&server_addr, sizeof(server_addr));

    char sendBuf[128];  
    int num = 0;
    while (1) {
        // 向服务端发送文件
        sprintf(sendBuf, "hello server %d\n", num ++ );
        send(cfd, sendBuf, strlen(sendBuf) + 1, 0);

        int len = recv(cfd, sendBuf, sizeof(sendBuf), 0);
        if (len == -1) {
            perror("recv");
            exit(-1);
        } else if (len == 0) {
            cout << "client closed..." << endl;
            exit(-1);
        } else if (len > 0) {
            printf("I am server, data: %s\n", sendBuf);
        }

        sleep(1);

    }


    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值