2014-10-19 63 views
1

所以我嘗試使用sendto()函數向客戶端發送消息。在sendto()函數中發送一個結構 - C語言

和sendto()函數的原型是這樣的:

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, 
       const struct sockaddr *dest_addr, socklen_t addrlen); 

但我想送一個結構作爲第二個參數。我能做到嗎?或者buf必須是一個字符串?

編輯:你看,我都能夠發送這樣的:

「的消息由‘標題’,其次是‘有效載荷’

你的消息頭應該包括以下內容:

uint8_t version; /* must be 1. If you receive anything else, discard*/ 
uint8_t ttl; /* must be 1. If you receive anything else, discard*/ 
uint16_t payload_length; /* bytes following the header */ 
uint32_t account_identifier; /* digits of your account name */ 
uint32_t source_address; /* unused for now, set to 0 and ignore. */ 
uint32_t destination_address; /* unused for now, set to 0 and ignore. */ 
uint16_t checksum; /* unused for now, set to 0 and ignore. */ 
uint16_t protocol; /* must be 1. If you receive anything else, discard*/" 

和有效載荷是一個文本字符串,如「你好」之類的。

我覺得像我送頭將發送所有的結構的唯一方式信息。對?

回答

2

您可以使用sendto發送任何連續的內存塊,因此不帶指針的struct就可以。但是,客戶需要能夠使用適當的佈局來處理該struct,這是非常有限的。

考慮一個簡單的struct這樣的:

struct One { 
    int a; 
    float b; 
    char c[20]; 
}; 

它可以在同一硬件上,當客戶端和服務器端的代碼被編譯相同的編譯器,使用相同的設置罰款。即使對於看起來很簡單的struct來說,稍微不同的硬件也會導致問題,儘管:endianness,填充,各種表示的大小等都將相同以使其工作。

如果您需要與其他硬件或其他編程語言的互操作性,您需要生成雙方都可以處理的特定結構,二進制或文本。

如果您struct有一個指針,你將無法發送和接收它沒有一些特殊的處理:

struct Two { 
    int a; 
    float b; 
    char* c; // <<<=== Not going to work 
}; 

當您需要發送的結構一樣,你發件人「連載」他們轉換爲可由接收端「反序列化」的字節數組,然後發送該緩衝區。接收此緩衝區的代碼將數據「解包」爲一個「struct」,根據需要分配內存,並將接收緩衝區中的數據複製到這個新分配的內存中。

struct以上可以如下被序列:表示長度塊的len由指針指向

  • 4個字節用於int
  • 4個字節用於float
  • 4字節c
  • len字節代表內容c
+0

雅互操作性不成問題。服務器的硬件是一樣的。 – umdcoder 2014-10-19 21:01:15

+0

帶指針的結構體是否也能發送? – umdcoder 2014-10-19 21:01:41

+1

@umdcoder不,它不是。一般來說,發送結構是一個糟糕的主意。不要使用結構作爲網絡協議。使用網絡協議作爲網絡協議。 – EJP 2014-10-19 21:04:21