recv()函数中的指针出错

时间:2013-10-30 05:42:21

标签: c sockets pointers segmentation-fault

我正在进行套接字编程,以实现我的应用程序中不同实体之间的通信。发送消息时,我在消息前面加上消息的长度,然后用\ 0终止它。我在循环中有recv(),如下所示:

void receive(int socket)
{
    int num_of_bytes_read = 0,  msg_len;
    char *msg = NULL, *msg_p = NULL;
    char recv_buf[MAX_LEN]; 

    while(num_of_bytes_read = recv(socket, recv_buf, MAX_LEN, 0))
    {
        if(msg == NULL)
        {
            memcpy(&msg_len, message, 4);
            msg_len = ntohl(msg_len);

            if((msg = (char *)(sizeof(char) * msg_len)) == NULL)
                systemError("Could not receive new message\n");

            printf("%p\n", msg);  /* prints 0xe!! Why is the address not 4B long??*/
            msg_p = msg;
        }

        if(memcpy(&msg_p, recv_buf, num_of_bytes_read) == NULL)
            systemError("memcpy failed in receive()\n");

        msg_p += num_of_bytes_read;
    }


    printf("%p\n", msg);                    /* prints (nil) !!!!!*/
    printf("%p\n", msg + sizeof(uint32_t)); /* prints 0x4 */

    /* pass the a pointer to the beginning of the message skipping msg_len*/
    int res = processMessage(msg + sizeof(uint32_t));
 }

当我运行该程序时,我明显得到分段错误,并出现以下错误: message = 0x4

msg 有什么问题?有人可以帮忙。

2 个答案:

答案 0 :(得分:3)

while(num_of_bytes_read = recv(socket, recv_buf, MAX_LEN, 0))

这已经错了。你应该测试> 0.如果num_of_bytes为零,则应关闭套接字,如果为-1,则应记录关联的errno,,例如使用perror(),并关闭套接字,并在两种情况下都停止读取。

    if(msg == NULL)
    {
        memcpy(&msg_len, message, 4);

只要message指向可寻址内存的四个字节,就可以成功。您没有提供有关该点的任何信息。目的仍然模糊不清。

        msg_len = ntohl(msg_len);

在这里,您假设message指向四个神奇地包含int的字节,该神奇地被设置为您准备将其视为消息长度的值。为什么,我不知道。你再次没有提供关于这一点的信息。

        if((msg = (char *)(sizeof(char) * msg_len)) == NULL)

这完全是胡说八道。某处有malloc()缺失吗?

            systemError("Could not receive new message\n");

无意义的错误消息。问题似乎是关于分配内存,但这是任何人的猜测。它当然与接收消息无关。

        printf("%p\n", msg);  /* prints 0xe!! Why is the address not 4B long??*/

在这里,您似乎认为地址应该是4B长。我不知道为什么。

    if(memcpy(&msg_p, recv_buf, num_of_bytes_read) == NULL)

您正在将数据复制到msg_p.地址这没有意义。此外,由于上面的循环条件不正确,此时num_of_bytes_read可能为-1,因此可能发生任何事情,包括尝试复制0xffffffff字节。

        systemError("memcpy failed in receive()\n");

如果msg_p地址为空,那么你可以到达这一行的唯一方法是,这是不可能的。从&来电中的&msg_p移除memcpy()。现在,如果systemError()为零,您只能进行此msg_p调用,这已经导致了SEGV,因此您仍然无法访问此行。这里指出了一些预防性编码。

    msg_p += num_of_bytes_read;

此时num_of_bytes_read再次为-1,向后发送指针而不是向前发送。

printf("%p\n", msg);                    /* prints (nil) !!!!!*/

Nil表示msg为零。

printf("%p\n", msg + sizeof(uint32_t)); /* prints 0x4 */

0x4再次表明msg为零。

您需要在指定的区域内改进您的代码。

答案 1 :(得分:2)

msg = (char *)(sizeof(char) * msg_len)

您正在根据msgmsg_len设置为某个地址。实际上与msg驻留在内存中的位置无关......