2011-07-23 4 views
7

C++サーバーからC#クライアントにデータを送信しようとしています。私はchar配列を送ることができました。しかし、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#を使用したことがないし、多分もっと良いものがあります。最初の場所でストリームからfloatを取得する簡単な方法がなかったのは奇妙だった?)

//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 

のC#のここ2つの問題がある側 - 1)最初のそれは127以上が0x80以上何も()(互換性のない構造を処理しません) 2)のために?いくつか信じられないほどの理由でそれはバイトを落とす!

が、これは右の私はまだ何か出て何もを把握しようとしてきたデータ

を受信した時に「TEMP」で行われます。 これがなぜ起こっているのかご存じですか?私は何か間違っていると確信しています... より良いアプローチのための提案?

どうもありがとう

答えて

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はストリームから読み込みたいデータ型を正確に指定できるように設計されているため、BinaryReaderはそれを行いません。

+0

'StreamReader'は' System.IO.StreamReader()として定義されています。ええ、私は 'BinaryReader'が良い選択肢かもしれないと思います。ありがとう、私はそれを試してみましょう。 – sg88

+0

ありがとうございます!試してみた - それは – sg88

1

ネットワークでは、番号を共通の形式に変換してから読み戻す必要があります。換言すれば、バイト以外のデータはカプセル化されるべきである。したがって、プログラミング言語に関係なく、これはあなたがする必要があります。私はあなたのコードに何が間違っているかについてはコメントできませんが、これはあなたの問題を解決するかもしれないし、後で頭痛を軽減するでしょう。アーキテクチャが64ビットであるか、または異なるエンディアンを使用するかどうかを考えます。

EDIT:
あなたの問題は署名付きの署名付きであり、Isakの答えで解決できると思いますが、私が言ったことはまだ気になります。

カプセル化に関する助けが必要な場合は、Beej's Network Guideをチェックしてください。ネットワークを介して浮動小数点をエンコードする方法のサンプルが必要です。

+0

うん、それについて知っている。メモリダンプが表示された場合、浮動小数点の一部は正常に転送されます。 – sg88

1

C#についてはわかりませんが、C++は浮動小数点(または他のデータ型)の内部バイナリ表現について保証していません。ご存知のように、これらの4バイトを使用して0.42を表すことができます: '0'、 '。'、 '4'、 '2'。

最も簡単な解決策は、 "2.1 9.9 12.1 94.9 2.1"のような人間が読める文字列を転送し、cin/cout/printf/scanfやfriendsを使用することです。

+0

'printf'は出力形式を保証していますか? – svick

+0

私は理論的には同意しますが、実際には、IEEE 754(doubleとfloatの両方を定義しています)とは異なる浮動表現が実際に使用されていますか? –

+0

(そしてbtw、c#は上記の標準で定義されているfloatとdoubleのフォーマットを指定しています)http://msdn.microsoft.com/en-us/library/aa691146(v=vs.71).aspx –

関連する問題