2

ちょっと長いタイトルですが…

私はこれらの例、特にメッセージのサイズをバイトストリームに書き込んだり読んだりする部分について見てきました
http://doc.trolltech.com/4.4/network-fortuneclient-client-cpp.html
http:/ /doc.trolltech.com/4.4/network-fortuneserver-server-cpp.html

しかし、私はC#でそれを理解できないようです。

StreamWriter writer = new StreamWriter(tcpClient.GetStream());
writer.Write(data.Length + data);

これはまったくうまくいきません。誰かが私に正しい方向への微調整を与えることができますか?

4

6 に答える 6

2

通常、最初に長さを送信します。両端は、長さがどのように見えるかについて合意する必要があります。たとえば、固定の 4 バイト長のプレフィックスをバイナリとして使用しても問題ない場合があります。

  byte[] data = ...
  int len = data.Length;
  byte[] prefix = Bitconverter.GetBytes(len);
  stream.Write(prefix, 0, prefix.Length); // fixed 4 bytes
  stream.Write(data, 0, data.Length);

明らかに、呼び出し元も同じことを行う必要があります。つまり、最初の 4 バイトを読み取って長さを取得します。読み取りの場合、受信側はデータを読みすぎないように注意する必要があります。1 つの方法は、ストリームを制限することです。たとえば、このクラスを使用して、読み取りすぎないストリームを取得できます。

常に 4 バイトを送信するオーバーヘッドが必要ない場合は、さらに興味深いエンコーディングが可能です。たとえば、msb を継続ブロックとして使用します。

参考までに、protobuf-netは、Google の「プロトコル バッファ」メッセージベースのフォーマットを中心に設計されたバイナリ シリアライザーです。多くの詳細を処理してくれるので、シリアライゼーション コードの記述に多くの時間を費やしたくない場合に便利です。QuickStart プロジェクトにソケットの例があります。

于 2008-10-15T07:43:36.063 に答える
1

私はこれがそれを行うべきだと思います:(私はあなたのデータが文字列であると仮定します)

ストリーム stream = tcpClient.GetStream();
Encoding encoding = Encoding.GetEncoding("エンコーディング名");

byte[] バイト = encoding.getBytes(data);

stream.Write(BitConverter.GetBytes((short)bytes.Length),0,2); // データが 64k より長くないことを願っています
stream.Write(bytes,0,bytes.Length);
于 2008-10-15T07:36:16.687 に答える
1

の代わりにdata.Length、次を試してください。

writer.Write(chr(data.Length) + data);

これにより、すべてのデータ ブロックの前に、その長さを示す 1 バイト (最大 255 バイト) が付けられます。あなたが要求したように、これはちょっとしたことです。:)

更新: C# はすべて Unicode などであることを思い出したので、chr() はおそらく 1 バイト以上を提供します。フィットするように調整します。

于 2008-10-15T07:18:43.820 に答える
0

Writeの代わりにWriteLine、Readの代わりにReadLineを使用...

純粋なテキスト メッセージを送信する場合は、メッセージの最後に改行文字を追加します。次に、この改行文字に遭遇するまでバイトを読み取り、バイトを文字列に変換します。便宜上、System.IO.StreamReader と System.IO.StreamReader は、この動作を 1 つのメソッド (WriterLine または ReadLine) に実装します。string lineSent = reader.ReadLine();

于 2009-03-02T23:13:38.953 に答える
0

「これが全然うまくいかない」と言うと、具体的に何がうまくいかないのか気になります。それらはソケットの両端にある .NET アプリケーションですか? もしそうなら、この答えを無視してください。そうでない場合、問題は整数のバイト順でしょうか? リトルエンディアンとビッグエンディアンの問題?このスレッドでは、次のように説明しています。

http://bytes.com/forum/thread225649.html

http://books.google.com/books?id=2zT5b2BS1OUC&pg=PA64&lpg=PA64&dq=c%23+sockets+integers+byte+ordering&source=web&ots=_ISzZZ6HHT&sig=tUHdNT0NGv0uxusmHG9YjFw6j9k&hl=en&sa=X&oi=book_result&resnum=2&ct=result

両端が .NET でない場合のもう 1 つの問題は、Unicode を送信しているのに、もう一方の端が ANSI 文字列を期待していることです。

于 2008-10-15T08:26:00.613 に答える
0

また、プレーンテキスト性を維持したい場合は、特定の最大サイズを指定し、string.Format を介して数値をパディングすることもできます。(たとえば、長さが 4 文字しか許可されていないとします) これにより、有用なデータストリーム内の数値の問題が回避され、デコードも簡素化されます。

最終的な平文の解決策は、長さとデータの間に - などの特定の文字を配置し、マイナスに達するまで一度に 1 文字ずつ取得し、取得した文字列をデコードし (もちろんマイナスは無視します)、それを使用して残りの文字列の長さと、その文字を間に追加するために変更する必要がある出力コード。

于 2008-10-15T08:52:56.440 に答える