You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unix套接字传递任意类型数据的实现问题及序列化必要性咨询

Unix套接字IPC传递任意类型数据的问题

我正在开展一个个人项目以深入理解Unix系统的进程间通信(IPC),用C语言编译了两个二进制程序,尝试通过Unix套接字实现进程间数据传递。我希望收发函数具备通用性,能传递任意类型数据(int、char、复杂结构体),为此设计了如下消息结构及收发函数:

enum DataType
{
    INT_TYPE,
    FLOAT_TYPE,
    CHAR_TYPE,
    STRUCT_TYPE,
};

struct Message
{
    int identifier;
    enum DataType data_type;
    void* data;
    size_t data_length;
};

发送函数实现

ssize_t Send_message(const int pSocket, struct Message pMessage)
{
    // Send the message over the socket
    ssize_t bytes_sent = send(pSocket, &pMessage, sizeof(struct Message), 0);

    if (bytes_sent == -1) 
    {
        perror("Error in ipc.c, Send_message: Error sending message");
        return -1;
    }

    if (bytes_sent != sizeof(struct Message)) 
    {
        fprintf(stderr, "Error in ipc.c, Send_message: Incomplete message sent\n");
        return -1;
    }

    if(pMessage.data_length > 0 && pMessage.data != NULL)
    {
        bytes_sent += send(pSocket, pMessage.data, pMessage.data_length, 0);

        if (bytes_sent == -1) 
        {
            perror("Error in ipc.c, Send_message: Error sending message");
            return -1;
        }

        if (bytes_sent != pMessage.data_length + sizeof(struct Message)) 
        {
            fprintf(stderr, "Error in ipc.c, Send_message: Incomplete message sent\n");
            return -1;
        }
    }
    
    printf("\nSent message with Request Type : %d, Identifier :%d, Data Lenght : %d \n", pMessage.request_type, pMessage.identifier, pMessage.data_length);

    return bytes_sent;
}

发送基础类型数据时,通过将数据转为void*传递,接收端再转回对应类型,该方式可正常工作:

struct Message response;
// ** Input here response.identifier
// ** Input here response.data_type 
// ** Input here response.data_length

char *string_val = "HELLO WORLD";
int int_val = 42; 
if(received_message.data_type == CHAR_TYPE)
{
  response.data = (void*)string_val;                
}
if(received_message.data_type == INT_TYPE)
{
  response.data = (void*)&int_val ;                
}

Send_message(pSocket, response);

遇到的问题

但传递如下包含char*指针的复杂结构体时,接收端仅能获取int和float值,无法访问char*指向的内容:

typedef struct {
int subparam1;
float subparam2;
char * subparam3;
} SubConfiguration;

SubConfiguration subconf;
// ** Fill in the struct

response.data = (void*)&subconf;

Send_message(pSocket, response);

接收函数实现

ssize_t Receive_message(const int pSocket, struct Message *pMessage)
{
    // Receive the message into the buffer
    ssize_t bytes_received = recv(pSocket, pMessage, sizeof(struct Message), 0);

    if (bytes_received != sizeof(struct Message)) 
    {
        perror("\n Error in ipc.c, Receive_message: Error receiving message");
        return -1;
    }

    if(pMessage->data_length > 0 )
    {
        pMessage->data = malloc(pMessage->data_length);
        bytes_received += recv(pSocket, pMessage->data, pMessage->data_length, 0);

        if (bytes_received != pMessage->data_length + sizeof(struct Message)) 
        {
            perror("\n Error in ipc.c, Receive_message: Error receiving message");
            return -1;
        }
    }

    printf("\nReceived message with Request Type : %d, Identifier :%d, Data Lenght : %d \n", pMessage->request_type, pMessage->identifier, pMessage->data_length);

    return bytes_received;
}

疑问

  1. 该需求(传递任意类型数据,包括带指针的复杂结构体)是否可实现?
  2. 我哪里出错了?
  3. 是否有必要引入Protocol Buffers(如protobuf)进行序列化与反序列化?

内容的提问来源于stack exchange,提问作者BigBurger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 02:57:52