Tạo cặp socket kết nối với hàm `socketpair`

Hàm socketpair là một hệ thống gọi trên Unix/Linux, giúp tạo ra hai socket đã được kết nối. Cặp socket này có thể sử dụng để truyền thông hai chiều giữa các tiến trình cùng nhau hoặc giữa tiến trình cha và con.

Khai báo của hàm socketpair như sau:

#include <sys/socket.h>

int socketpair(int giao_thức, int loai, int thuat_toan, int mang_socket[2]);
  • giao_thức: Xác định miền truyền thông, thường dùng AF_UNIX cho truyền thông cục bộ.
  • loai: Loại socket, ví dụ SOCK_STREAM (có kết nối) hoặc SOCK_DGRAM (không có kết nối).
  • thuat_toan: Thông thường là 0, đại diện cho giao thức mặc định.
  • mang_socket: Mảng chứa hai file descriptor của cặp socket được tạo.

Tính năng chính của socketpair

  • Giao tiếp hai chiều: Cả hai socket đều có khả năng đọc và ghi dữ liệu.
  • An toàn về danh tính: Không gắn vào đường dẫn hay địa chỉ mạng nào, chỉ truy cập qua file descriptor.
  • Nhanh chóng: Dữ liệu được chuyển trực tiếp trong kernel mà không cần qua stack mạng.

Ví dụ mã nguồn: Truyền thông giữa tiến trình cha và con

Dưới đây là một ví dụ về cách sử dụng socketpair để thực hiện truyền thông giữa tiến trình cha và con. Tiến trình cha gửi tin nhắn tới tiến trình con và nhận phản hồi từ nó.

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

int main() {
    int mang_moi_truong[2];
    char nhan_xu_ly[256];
    pid_t tien_trinh_con;

    // Tạo cặp socket
    if (socketpair(AF_UNIX, SOCK_STREAM, 0, mang_moi_truong) == -1) {
        perror("Không thể tạo cặp socket");
        exit(EXIT_FAILURE);
    }

    tien_trinh_con = fork();

    if (tien_trinh_con == -1) {
        perror("Lỗi khi tạo tiến trình con");
        close(mang_moi_truong[0]);
        close(mang_moi_truong[1]);
        exit(EXIT_FAILURE);
    }

    if (tien_trinh_con > 0) { 
        // Tiến trình cha
        close(mang_moi_truong[1]); 

        const char *thong_diep_cha = "Xin chào từ tiến trình cha!";
        write(mang_moi_truong[0], thong_diep_cha, strlen(thong_diep_cha) + 1);

        read(mang_moi_truong[0], nhan_xu_ly, sizeof(nhan_xu_ly));
        printf("Tiến trình cha nhận được: %s\n", nhan_xu_ly);

        close(mang_moi_truong[0]);
    } else { 
        // Tiến trình con
        close(mang_moi_truong[0]);

        char nhan_cha[256];
        read(mang_moi_truong[1], nhan_cha, sizeof(nhan_cha));
        printf("Tiến trình con nhận được: %s\n", nhan_cha);

        const char *phản_hồi = "Xin chào từ tiến trình con!";
        write(mang_moi_truong[1], phản_hồi, strlen(phản_hồi) + 1);

        close(mang_moi_truong[1]);
    }

    return 0;
}

Thẻ: C Unix ipc

Đăng vào ngày 17 tháng 6 lúc 21:38