2011-07-23 159 views
7

我想從C++服務器發送一些數據到C#客戶端。我能夠發送字符數組。但浮點數組存在一些問題。發送float數組從C++服務器到C#客戶端

這是在C++服務器端

float* arr; 
arr = new float[12]; 
//array init... 
if((bytecount = send(*csock, (const char*)arr, 12*sizeof(float), 0))==SOCKET_ERROR){ 
} 

的代碼,所以是的,我想送過來尺寸12

的float數組這裏是爲客戶端的代碼。 (奇怪的是,有沒有簡單的方法來獲得浮出擺在首位流的。我從來沒有使用C#之前,也許有更好的東西?)

//get the data in a char array 
streamReader.Read(temp, 0, temp.Length); 
//**the problem lies right here in receiving the data itself 

//now convert the char array to byte array 
for (int i = 0; i < (elems*4); i++)   //elems = size of the float array 
{ 
    byteArray = BitConverter.GetBytes(temp[i]); 
    byteMain[i] = byteArray[0]; 
} 

//finally convert it to a float array 
for (int i = 0; i < elems; i++) 
{ 
    float val = BitConverter.ToSingle(byteMain, i * 4); 
    myarray[i] = val; 
} 

讓我們來看看內存轉儲兩側和問題將是明確的 -

//c++ bytes corresponding to the first 5 floats in the array 
//(2.1 9.9 12.1 94.9 2.1 ...) 
66 66 06 40 66 66 1e 41  9a 99 41 41 cd cc bd 42 66 66 06 40 

//c# - this is what i get in the byteMain array 
66 66 06 40 66 66 1e 41  fd fd 41 41 fd 3d ? 42 66 66 06 40 

這裏有2個問題關於C#副作用 1)首先它不處理上述0x80的任何東西(127以上)(不兼容的結構) 2)?一些令人難以置信的原因,它降低了一個字節!

,這發生在「臨時」就在接收到數據

我一直在試圖找出仍然出來的東西,但沒有時間。 你知道爲什麼會發生這種情況嗎?我敢肯定我做錯了什麼... 建議更好的方法?

非常感謝

回答

5

目前尚不清楚,從你的代碼是什麼streamReader變量指向(即什麼是它的類型?),但我會建議你使用BinaryReader代替。這樣的話,你可以只讀取數據one float at a time並與byte[]陣列都從來沒有打擾:

var reader = new BinaryReader(/* put source stream here */) 
var myFloat = reader.ReadSingle(); 
// do stuff with myFloat... 
// then you can read another 
myFloat = reader.ReadSingle(); 
// etc. 

不同的讀者做不同的事情的數據。例如,文本閱讀器(和流式閱讀器)將假定所有文本都是特定編碼的文本(如UTF-8),並可能以您沒有預料到的方式解釋數據。 BinaryReader不會這樣做,因爲它旨在讓您準確指定要從流中讀出的數據類型。

+0

'StreamReader'被定義爲'System.IO.StreamReader()'。是的,我認爲'BinaryReader'可能是一個更好的選擇。謝謝,讓我試試看。 – sg88

+0

謝謝!!嘗試和測試它 - 它的作品 – sg88

1

在網絡中,您應該始終將您的號碼轉換爲通用格式,然後回讀。換句話說,除字節以外的任何數據都應該被封裝。所以不管你的編程語言如何,這都是你需要做的。我無法評論你的代碼出了什麼問題,但這可能會解決你的問題,並且稍後會節省一些頭痛的問題。想想架構是64位還是使用不同的endian。

編輯:
我猜你的問題在於簽署無符號,可與伊薩克的答案來解決,但仍介意我說的話。

如果你需要封裝檢查Beej的網絡指南的幫助。它應該有一個示例如何通過網絡編碼浮點數。

+0

是我知道的。只是如果你看到內存轉儲,一些浮點數就會轉移得很好! – sg88

1

我不確定C#,但C++不保證浮點數(或任何其他數據類型)的內部二進制表示形式。對於你所知道的,0.42可能用這4個字節表示:'0','。','4','2'。

最簡單的解決方案是傳輸人類可讀的字符串,如「2.1 9.9 12.1 94.9 2.1」,並使用cin/cout/printf/scanf和朋友。

+0

'printf'是否可以保證輸出的形式? – svick

+0

我理論上同意,但在實踐中,實際上是否存在與IEEE 754(定義double和float兩者)一樣的使用中的任何不同的浮點表示? –

+0

(和順便說一句,c#確實指定了float和double的格式,如上面提到的標準中所定義的那樣)http://msdn.microsoft.com/en-us/library/aa691146(v=vs.71).aspx –

相關問題