2009-12-07 36 views
0

我想通過UDP套接字發送我的結構。如何將c中的char []複製到我的結構中

結構數據包int seqnum; char data [BUFFERSIZE]; };因此,發件人

bytes = sizeof(packet); 
char sending[bytes]; 
bzero(sending, bytes); 
memcpy((void *) sending, (void *) &packet, sizeof(bytes)); 
bytes = sendto(sockfd, sending, sizeof(sending), 0, 
    (struct sockaddr *) &client, clientSize); 

所以我希望我的副本結構成的char []。

在接收機我有

int bytes; 
bytes = sizeof(struct Packet); 
char recv[bytes]; 
bytes = recvfrom(sockfd, recv, bytes, 0, 
    (struct sockaddr *) &client, &clientSize); 
memcpy((void *) currentpkt, (void *) recv, bytes); 

然而與的memcpy((無效*)currentpkt,(無效*)的recv,字節)的接收器;我得到一個錯誤:

error: cannot convert to a pointer type

我在做什麼錯?有沒有更好的方式通過UDP套接字發送我的結構?

***** UPDATE *****

感謝大家的回答。最後我錯過了'&',但我的代碼現在看起來像這樣。

發件人:

void udt_send(struct Packet packet) { 
    int bytes; 
    bytes = sendto(sockfd, (char *) &packet, sizeof(packet), 0, 
      (struct sockaddr *) &client, clientSize); 
} 

接收機:

bytes = recvfrom(sockfd, (char *) &currentpkt, bytes, 0, 
     (struct sockaddr *) &client, &clientSize); 

在C其漂亮的,我們只需將它轉換爲一個char和發送的字節數過來。

+0

什麼是'currentpkt'? – 2009-12-07 04:24:50

+0

struct packet currentpkt; //全局變量 – 2009-12-07 04:28:52

+1

問題#1:當不需要使用全局變量時,不要使用全局變量._ – 2009-12-07 04:30:47

回答

3

currentpkt是結構類型;你需要得到一個指向該結構的指針才能使其工作:

memcpy(&currentpkt, recv, bytes); 

對於第二個問題,還有其他一些問題。如果您收到的數據包中的字節數比sizeof(struct Packet)多?正如現在寫的,你會超出你的結構。

如果客戶端和服務器應用程序是使用不同的編譯器或設置編譯的,或者在具有不同字節順序的平臺上編譯?在這種情況下,兩個平臺上的結構體可能會有不同的大小,並且可能會以不同的方式放在內存中。

+0

啊......謝謝,這個修正了=) – 2009-12-07 04:33:04

+1

@Bernie:確保你解決James的其他問題。對於溢出,更好地使用'memcpy'的第三個參數;只要確保你處理太多和太少的數據。對於字節順序,請看'ntoh *'和'hton *'函數(例如ntohl)。全局變量可以轉換爲函數參數,或者(有時)作爲適當結構的字段添加。 – outis 2009-12-07 05:21:04

1

所以我在想currentpktstruct Packet,你真的想說&currentpkt

我也可能會注意到memcpy()已經有void *參數,所以不需要(void *)強制轉換。

+0

感謝您的提示。我會刪除那些void *的。 – 2009-12-07 04:32:32

0

memcpy((void *) currentpkt, (void *) recv, bytes);

你的錯誤信息提示偏色問題。 recv沒問題,因爲它是char[](沒問題轉換爲(void *))。問題必須是currentpkt不能是指針類型。

它沒有在您的代碼段中聲明,所以我不知道它是什麼,但我會從那裏開始。

0

從整個結構中執行memcpy確實是邪惡的:-)。首先根據架構不同,數據可能會有所不同。如果架構與另一方不同,會怎麼樣?在不同的編譯器之間使用關鍵字__packed也是不可移植的。

據我所知,最好的方法就是使用一個API,比如PHP pack/unpack。這使得代碼真正的可移植,而不使用編譯器特定的醜陋關鍵字,如__packed。

我沒有找到任何包裝/解包在網上,所以我寫我自己的。

例如從二進制數據解壓兩個字:

pbuf_unpack(p_bts, "ww", &hdr, &ver); 

p_bts is binary data 
    "ww" describes the data structure 
    hdr and ver is where to put the datause an API like the PHP pack/unpack. 

另一個更廣泛例如:

pbuf_unpack(p_entry, "bbbbbbbbww", 
     &atrb_mbr.def_boot_par, &atrb_mbr.head_start, &atrb_mbr.sec_start, 
     &atrb_mbr.cyl_start, &atrb_mbr.type, &atrb_mbr.head_end, 
     &atrb_mbr.sec_end, &atrb_mbr.cyl_end, &atrb_mbr.start_sec_pbr, 
     &atrb_mbr.sec_per_par); 

包裝很容易:

pbuf_pack(boot_buf, "sdsdhbhbhhbhhhwwbbbwsdsd", sizeof(fat_jmp_boot_t), 
     boot.jmp, sizeof(fat_oem_nm_t), boot.oem_nm, boot.n_bps, boot.n_spc, 
     boot.n_rs, boot.n_fs, boot.n_rde, boot.n_ts16, boot.media_des, 
     boot.n_fatsz16, boot.n_spt, boot.n_hds, boot.n_hs, boot.n_ts32, 
     boot.drv_no, boot.rsrvd1, boot.boot_sig, boot.vol_id, 
     sizeof(fat_vol_lbl_t), boot.lbl, sizeof(fat_vol_type_t), boot.type); 

它不僅創建便攜式代碼,而且它也很漂亮;)

相關問題