2016-02-05 29 views
0

我正在通过TCP向客户端应用程序发送一个dirtree。迪尔节点是看起来像这样的结构:通过TCP发送序列化目录树

struct node { 
     char *name; 
     int count_subnodes; 
     struct node **subnodes; 
}; 

要序列:

void serialize(void *buffer, struct node *n, int *c){ 
    int i; 
    if(!n) 
     return; 
    memcpy(buffer+(*c), n, sizeof(*n)); 
    *c+=sizeof(n); 
    for(i = 0; i < n->count_subnodes; i++){ 
     serialize(buffer, n->subnode[i], c); 
    } 
} 

我在做什么错?当我为子节点递归调用序列化时,它会发生段错误。另外,我是否需要任何种类的标记来划定界限,以便我可以在客户端重新构建树?

编辑:c是保持缓冲区当前位置的计数。

编辑2:错字。它是sizeof(* n)而不是c。对不起

+0

也许你的缓冲区太小?很难说不知道有关实际树或缓冲区的任何信息。 –

+0

我给了测试的大内存。我做了'buffer = calloc(600,1)'这对我的例子来说足够大。你看到任何执行问题? – Neo

回答

-1

您正在复制结构n,并给它的尺寸为c,这是一个int*。我认为你的问题是这条线:

memcpy(buffer+(*c), n, sizeof(c)); 

此外,你真的不想序列化结构本身。如果你这样做了,那么当你真的想发送名字的时候,你会发送一个指向这个名字的指针。

我认为你需要序列化name以及子节点数。也许是这样的:

int name_length = strlen(n->name + 1); /* +1 for null terminator. */ 
memcpy(buffer+(*c), n->name, name_length); 
*c += name_length; 
memcpy(buffer+(*c), &n->count_subnodes, sizeof(n->count_subnodes)); 
*c += sizeof(n->count_subnodes); 

千万记住,对于不同的系统串行二进制数据时,你可能会遇到endianness问题。

确保您将buffer分配到足够大。超过buffer肯定会出现段错误。它也可能是你最初打电话给serialize。您还需要确保您的node树在没有悬挂指针的情况下有效。你必须通过有效int*c

您可能想要发布调用代码的最小示例。

+0

对不起。这是一个错字。改变了它。 – Neo

+1

为什么这会导致段错误,而不仅仅是垃圾序列化? –

+0

答案通常没有问题。 –

1
  1. 你怎么知道你的缓冲区够大?

  2. sizeof(n)会给出指针的大小,而不是结构体;使用sizeof(*n)

  3. 检查n->subnode[i]NULL

+0

你是对的2.但我把它改为sizeof(* n),我仍然陷入seg故障。对于1:我相信尺寸足够大。有了gdb,我可以看到在我调用子节点序列化的时候segfaults – Neo