2014-11-23 43 views
0

考慮使用Borland公司2007年和印UDP服務器和客戶端以下最低程序:正確發送,並通過印UDP接收結構

struct DATA_PACKAGE 
{ 
    int t; 
    int x; 
    int y; 
}; 

void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
    DATA_PACKAGE a; 
    a.t = 3; 
    a.x = 2; 
    a.y = 1; 
    Form1->Memo1->Lines->Add("sent " + IntToStr(sizeof(DATA_PACKAGE))); 
    Form1->UDPClient1->SendBuffer(server,port,RawToBytes(&a, sizeof(DATA_PACKAGE))); 
} 

void __fastcall TForm1::UDPServer1UDPRead(TObject *Sender, TBytes AData, 
     TIdSocketHandle *ABinding) 
{ 
    DATA_PACKAGE r; 
    Form1->Memo1->Lines->Add("received " + IntToStr(sizeof(AData))); 
    BytesToRaw(AData, &r, sizeof(AData)); 
    Form1->Memo1->Lines->Add(IntToStr(r.t) + " " + IntToStr(r.x) + " " + IntToStr(r.y)); 
} 

輸出:

sent 12 
received 4 
3 4717901 0 

首先,爲什麼發送12,但只接收4個字節?

其次發生了什麼x和y?

當我改變T,X的數據類型,Y短,我得到:

sent 6 
received 4 
3 2 0 

環顧四周,我發現指針的包裝結構體的(以及可能的字節順序?)是很重要的,然而,我無法找到一個明確的指導如何正確設計。

+0

接收到的數據取決於UDP通信的另一端。如果另一端像回顯服務器一樣工作,您可能會希望收到與之前發送的數據相同的數據。如果不知道另一方如何工作,很難看出問題所在。 – 2014-11-23 11:33:44

+0

如果我正確理解你,你的意思是服務器端?該程序(用於測試目的)將數據發送給自己,因爲它是客戶端和服務器之一。 – 2014-11-23 11:44:30

+0

'sizeof(TBytes)'看起來很可疑。什麼是'TBytes'?如果這是一些類,sizeof可能會給出類的大小,而不是它包含的數據。 – 2014-11-23 11:56:21

回答

2

TBytes是字節的動態數組,它是由RTL實現爲指針,這就是爲什麼sizeof(AData)正在返回4.不要用sizeof(AData),使用AData.Length屬性,而不是:

void __fastcall TForm1::UDPServer1UDPRead(TObject *Sender, TBytes AData, 
     TIdSocketHandle *ABinding) 
{ 
    DATA_PACKAGE r; 
    Form1->Memo1->Lines->Add("received " + IntToStr(AData.Length)); 
    BytesToRaw(AData, &r, AData.Length); 
    Form1->Memo1->Lines->Add(IntToStr(r.t) + " " + IntToStr(r.x) + " " + IntToStr(r.y)); 
} 
+0

謝謝,這是問題。只是澄清:如果我的結構包含一個動態對象(如AnsiString或向量),事務將不會這樣工作,對吧? – 2014-11-24 18:34:42

+1

這是正確的。您不能通過套接字發送指針,您必須將數據序列化爲扁平格式。 – 2014-11-24 19:48:56