2013-02-08 87 views
0

我只是在C中使用流式套接字,但是我在阅读从服务器应用程序返回的数据包时遇到问题。下面的代码显示了在客户端和服务器端使用的结构。从流套接字读取数据包的C错误

struct packet 
{ 
    uint16_t f1; 
    uint16_t f2; 
    uint32_t f3; 
    uint16_t pf1; 
    uint32_t pf2; 
}; 

用于发送服务器端:

char buffer[14]; 
struct packet myPacket; 

myPacket.f1 = 2321; 
myPacket.f2 = 4423; 
myPacket.f3 = 2134; 
myPacket.pf1 = 765; 
myPacket.pf2 = 9867; 

htonPacket(myPacket, buffer); 

函数数据打包到缓冲器。拆包和印刷

void htonPacket(struct packet h, char buffer[14]) { 
    uint16_t u16; 
    uint32_t u32; 

    u16 = htons(h.f1); 
    memcpy(buffer+0, &u16, 2); 

    u16 = htons(h.f2); 
    memcpy(buffer+2, &u16, 2); 

    u32 = htonl(h.f3); 
    memcpy(buffer+4, &u32, 4); 

    u16 = htons(h.pf1); 
    memcpy(buffer+8, &u16, 2); 

    u32 = htonl(h.pf2); 
    memcpy(buffer+10, &u32, 4); 
} 

客户端:

void ntohPacket(struct packet* h, char buffer[14]) { 
    uint16_t u16; 
    uint32_t u32; 

    memcpy(&u16, buffer+0, 2); 
    h->f1 = ntohs(u16); 

    memcpy(&u16, buffer+2, 2); 
    h->f2 = ntohs(u16); 

    memcpy(&u32, buffer+4, 4); 
    h->f3 = ntohl(u32); 

    memcpy(&u16, buffer+6, 2); 
    h->pf1 = ntohs(u16); 

    memcpy(&u32, buffer+8, 4); 
    h->pf2 = ntohl(u32); 
} 

印刷紧缩数据:

printf("myPacket.f1: %d\n", myPacket.f1); 
printf("myPacket.f2: %d\n", myPacket.f2); 
printf("myPacket.f3: %d\n", myPacket.f3); 
printf("myPacket.pf1: %d\n", myPacket.pf1); 
printf("myPacket.pf2: %d\n", myPacket.pf2); 

当我打印值,很明显的,我有一些问题或者解决或写入错误的内存位置,但我似乎无法找到该错误。

myPacket.f1: 2321 
myPacket.f2: 4423 
myPacket.f3: 2134 
myPacket.pf1: 2134 
myPacket.pf2: 50135040 
+1

为什么所有的东西都从一个结构复制到一个变量,然后调整endianness和memcpy?你可以一口气完成'dst-> f1 = htons(src-> f1)'。只需要'struct's来处理东西,而不是单个字节的混乱(确保你必须小心编译器不要偷懒)。我认为这样重做你的代码可以解决你的问题。 – vonbrand 2013-02-08 21:31:36

+0

我正在学习,我只是扩展了我在封包上发现的一个例子。感谢您的建议。 – dsell002 2013-02-08 21:41:28

+0

@ vonbrand:作为回答,你会得到我的+票;) – nneonneo 2013-02-08 21:45:49

回答

2

好,您正在使用不同的偏移量为您memcpy操作,所以当然你会得到垃圾...

memcpy(buffer+0, &u16, 2); 
memcpy(buffer+2, &u16, 2); 
memcpy(buffer+4, &u32, 4); 
memcpy(buffer+8, &u16, 2); 
memcpy(buffer+10, &u32, 4); 

memcpy(&u16, buffer+0, 2); 
memcpy(&u16, buffer+2, 2); 
memcpy(&u32, buffer+4, 4); 
memcpy(&u16, buffer+6, 2); 
memcpy(&u32, buffer+8, 4); 

你的最后行ntohPacket应该是

memcpy(&u16, buffer+8, 2); 
h->pf1 = ntohs(u16); 

memcpy(&u32, buffer+10, 4); 
h->pf2 = ntohl(u32); 
+0

Doh,谢谢。然而,纠正后,更有趣的事情出现了。现在最后的值与我所期望的稍有不同。 myPacket.pf2:9728当我发送9867. – dsell002 2013-02-08 21:34:09

+1

我只是做@vonbrand建议(在他的评论)。保持所有这些指数总有一天会让你痛苦不堪。 – nneonneo 2013-02-08 21:37:06

1

您的memcpy偏移量是错误的。修正:

memcpy(&u16, buffer+0, 2); 
h->f1 = ntohs(u16); 

memcpy(&u16, buffer+2, 2); 
h->f2 = ntohs(u16); 

memcpy(&u32, buffer+4, 4); 
h->f3 = ntohl(u32); 

memcpy(&u16, buffer+8, 2); <-- here 
h->pf1 = ntohs(u16); 

memcpy(&u32, buffer+10, 4); <-- here 
h->pf2 = ntohl(u32); 
1

为什么所有的东西都从一个结构复制到一个变量,然后调整字节顺序和memcpy?你可以一口气完成dst->f1 = htons(src->f1)。只需要struct就可以处理东西,而不是单个字节的傻瓜(当然,你必须小心编译器不要偷懒)。我认为这样重做你的代码可以解决你的问题。

+0

+1,这是最好的建议。 – nneonneo 2013-02-09 00:31:46