【问题标题】:Using ioctl(), read() and malloc() to receive a message from server not working properly使用 ioctl()、read() 和 malloc() 接收来自服务器的消息无法正常工作
【发布时间】:2026-01-29 11:05:01
【问题描述】:

我正在尝试用 C 语言制作一个简单的服务器客户端程序。在客户端上我尝试从服务器接收消息,但消息的大小没有预先确定。因此,我想检查有多少字节进来,malloc 的大小合适。

我尝试使用ioctl,但它似乎获得了我想要的信息为时已晚。 这就是我所拥有的。

char *message_from_server;
int length;
while(1){
    ioctl(socket, FIONREAD, &length);
    message_from_server = malloc(length);
    read(socket, message_from_server, length);
}

第一次使用时,length 为 0。第二次,长度等于第一条消息的长度。如果我在阅读后添加ioctl(socket, FIONREAD, &length); 行,这可能会给我分配正确的空间量带来麻烦。这甚至是解决我的问题的有效方法吗?

我听说有人可以使用realloc 来解决我的问题,但我正在努力寻找如何解决我的问题。如果这是一种更好的方法,我很乐意提供任何提示。

谢谢!

【问题讨论】:

  • 只有 TCP,传入数据的大小是预先确定的。它将是一个字节或更大的东西。如果您试图通过使用 ioctl 'peeking' 来实现超过一个再见的应用程序消息,或者假设 read() 将始终加载长度超过一个字节的完整消息的缓冲区,那么您很快就会遇到麻烦。

标签: c sockets client


【解决方案1】:

realloc 允许您增加内存块的大小,同时保留其内容。

所以,在你的情况下:

  1. 传入数据包的读取大小
  2. 更新内存块以存储数据包,保留之前读取的内容
  3. 读取数据包
  4. 转到 1. 或退出

您的代码应如下所示:

/* memory to store message, initially, no memory */
char *message_from_server = NULL;
/* size of memory */
int total_length = 0;

/* sizeof incoming packet*/
int packet_lentgh;

/* position to write in memory */
int offset;

while(1){
    /* read size of incoming packet*/
    ioctl(socket, FIONREAD, &packet_lentgh);

    if (0 != packet_lentgh)
    {
        /* something is ready to be read on socket */

        /* update memory size */
        total_length += packet_lentgh;

        /* allocate much memory*/
        message_from_server = realloc(message_from_server, total_length);
        if (NULL == message_from_server)
        {
            perror("realloc");
            abort();
        }

        /* compute the position to write in memory */
        offset = total_length - packet_lentgh;

        /* read the packet */
        read(socket, message_from_server + offset, packet_lentgh);
    }
    else
    {
        /* nothing to read 
           wait for packet or stop loop... */
    }
}

【讨论】:

  • 抱歉回答晚了。谢谢!