2013-02-08 36 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