2

I am doing socket programming for achieve communication between different entities in my application. When sending a message, I prefix the message with the length of the message and I terminate it with \0. I have recv() in a loop as follows:

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));
 }

When I run the program I obviously get segmentation fault with the following error: message=0x4

What is wrong with msg?? Can someone please help.

4

2 回答 2

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为零。

您需要在指示的区域中改进您的代码。

于 2013-10-30T06:00:49.230 回答
2

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

您正在msg基于msg_len. 实际上与味精在内存中的位置无关......

于 2013-10-30T05:45:21.500 回答