4.35、本地套接字

4.35、本地套接字

  • 1.本地套接字的介绍
  • 2.本地套接字通信的流程
  • 3.本地套接字代码编写
    • ①服务端
    • ②客户端

1.本地套接字的介绍

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

  • 有关系的进程间的通信
  • 没有关系的进程间的通信
  • 本地套接字实现流程和网络套接字类似,一般呢采用TCP的通信流程。
  • ip地址的类型(我们应该使用sockaddr_un)
    4.35、本地套接字_第1张图片

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 
#include 
#include 
#include 
#include 

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 
#include 
#include 
#include 
#include 

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;
}

你可能感兴趣的:(服务器,网络,unix)