域套接字epoll模型C语言demo

server: 

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

#define SOCKET_PATH "/tmp/mysocket.sock"
#define MAX_EVENTS 10
#define BUFFER_SIZE 256

void handle_client(int client_socket) {
    char buffer[BUFFER_SIZE];
    ssize_t bytes_read = read(client_socket, buffer, sizeof(buffer) - 1);
    if (bytes_read > 0) {
        buffer[bytes_read] = '\0'; // null-terminate the string
        printf("Received: %s\n", buffer);
    }
    close(client_socket);
}

int main() {
    int server_socket, client_socket, epoll_fd;
    struct sockaddr_un addr;
    struct epoll_event event, events[MAX_EVENTS];

    // 创建 UNIX 域套接字
    server_socket = socket(AF_UNIX, SOCK_STREAM, 0);
    if (server_socket < 0) {
        perror("socket error");
        exit(EXIT_FAILURE);
    }

    // 设置套接字地址
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);

    // 绑定套接字
    unlink(SOCKET_PATH); // 移除已有的套接字文件(如果存在)
    if (bind(server_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("bind error");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    // 开始监听客户端连接
    if (listen(server_socket, SOMAXCONN) < 0) {
        perror("listen error");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    // 创建 epoll 实例
    epoll_fd = epoll_create1(0);
    if (epoll_fd < 0) {
        perror("epoll_create1 error");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    // 将服务器套接字添加到 epoll 实例中
    event.events = EPOLLIN;
    event.data.fd = server_socket;
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_socket, &event) < 0) {
        perror("epoll_ctl error");
        close(epoll_fd);
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    printf("Server is running, waiting for connections...\n");
    
    while (1) {
        int n = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
        for (int i = 0; i < n; i++) {
            if (events[i].data.fd == server_socket) {
                // 接收新的客户端连接
                client_socket = accept(server_socket, NULL, NULL);
                if (client_socket < 0) {
                    perror("accept error");
                    continue;
                }
                // 将客户端套接字添加到 epoll 中
                event.events = EPOLLIN;
                event.data.fd = client_socket;
                if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_socket, &event) < 0) {
                    perror("epoll_ctl for client error");
                    close(client_socket);
                }
            } else {
                // 处理客户端消息
                handle_client(events[i].data.fd);
            }
        }
    }

    close(epoll_fd);
    close(server_socket);
    return 0;
}

client

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

#define SOCKET_PATH "/tmp/mysocket.sock"
#define MESSAGE "Hello, Server!"

int main() {
    int client_socket;
    struct sockaddr_un addr;

    // 创建 UNIX 域套接字
    client_socket = socket(AF_UNIX, SOCK_STREAM, 0);
    if (client_socket < 0) {
        perror("socket error");
        exit(EXIT_FAILURE);
    }

    // 设置套接字地址
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1);

    // 连接到服务器
    if (connect(client_socket, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("connect error");
        close(client_socket);
        exit(EXIT_FAILURE);
    }

    // 发送消息
    if (send(client_socket, MESSAGE, strlen(MESSAGE), 0) < 0) {
        perror("send error");
    }

    // 关闭客户端套接字
    close(client_socket);
    return 0;
}

编译运行

# 编译服务器端和客户端
gcc -o server server.c
gcc -o client client.c

# 先运行服务器
./server &

# 然后运行客户端
./client

记录用

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值