1

だから私はソケットを使用して同期ペイントプログラムのようなものを作成しようとしています.私はサーバー側..とクライアント側を持っており、サーバーからクライアントにinkCollectionを送信しようとしています.これは単純なテキストに対して機能しますが、私はインクコレクションを送信できないようです.または、データがより速く転送されるように、最後のストロークを送信するのを手伝っていただければさらにクールです.Hereは私が試してきたもののいくつかのコードです:

ストロークの送信:

        byte[] data;
        using (MemoryStream ms = new MemoryStream())
        {
            inkcanvas.Strokes.Save(ms);
            data = ms.ToArray();
        }

        svr.SendToAll("u getting some strokes");
        svr.SendStrokes(data);

svr.SendStrokes(byte[] データ):

 public void SendStrokes(byte[] data)
    {
        for (int i = 0; i < no; i++)
        {
            byte[] dt = data;
            accepted[i].Send(dt);
        }

            MessageBox.Show("dONE");
    }

これはクライアント側にあります:

 byte[] buffer=new byte[1024];
                MessageBox.Show("receiving strokes");
                int rec = conn.Receive(buffer, 0, buffer.Length, 0);
                if (rec <= 0)
                    throw new SocketException();
                MessageBox.Show("strokes received");
                //Array.Resize(ref buffer, rec);
                using (MemoryStream ms = new MemoryStream(buffer))
                {
                    inkcanvas.Strokes = new System.Windows.Ink.StrokeCollection(ms);
                    ms.Close();
                }
                MessageBox.Show("strokes added");

これらのまったく同じメソッドは文字列に対して完全に機能しますが、ストロークコレクションで実行しようとすると失敗します。クライアントには何も表示されず、サーバー側で次の SocketException が発生します: 既存の接続がリモートホストによって強制的に閉じられました.

しかし、皆さんがこれを行う方法についてより良い方法を手に入れたら、それは素晴らしいことです...それは私が見逃しているものですか? つまり、バイト配列に変換されたテキストで機能する場合...なぜこのストロークコレクションで機能するのでしょうか?

ありがとう!

編集:サンプルコードで私を助けることができると思いますか? 私は本当にそれを実装しているようには見えません。

4

2 に答える 2

2

プロトコルを設計または実装するのを忘れていました! TCP 経由で大量のバイトを送信するだけで、受信者がそれを理解できると仮定することはできません。

TCP 経由で送信しようとしている一連のストロークで構成されるアプリケーション メッセージがあります。ただし、TCP はバイト ストリーム サービスであり、アプリケーション メッセージ サービスではありません。したがって、メッセージを転送用にパッケージ化し、受信時にアンパッケージ化するには、ある種のアプリケーション メッセージ プロトコルが必要です。しかし、あなたはそのようなコードを書いていません。したがって、基本的には魔法で機能することを期待しています。

プロトコルを定義します。たとえば、次のようになります。

キャンバス ストロークは、キャンバス ストロークを示す「1」バイト、ネットワーク バイト順でのストローク オブジェクト内のバイト数を示す 4 バイト、およびストローク データによって送信されます。レシーバーは最初のバイトを読み取り、それがキャンバス ストローク オブジェクトであることを識別します。次に、受信側は次の 4 バイトを読み取って長さを決定します。受信側は、そのバイト数を蓄積し (必要に応じて複数の読み取りを使用)、再構築されたキャンバス ストローク オブジェクトを処理します。

記述されたプロトコル定義を作成するステップをスキップしないでください。

次に、問題が発生した場合は、次の便利なトラブルシューティング ガイドに従ってください。

  1. 送信者は仕様に従っていますか? そうでない場合は、停止してください。送信者が壊れています。

  2. 受信機は仕様に従っていますか?そうでない場合は、停止してください。受信機が壊れています。

  3. ストップ、仕様が壊れています。

シンプルにしたい場合は、データを base64 に変換し、各メッセージを 1 行のテキストとしてエンコードできます。これにより、関数を使用ReadLineして正確に 1 つのメッセージを取得できます。次に、「S」(「ストローク」) のようなメッセージ形式を使用し、その後に base64 形式のデータを続けます。関数を使用しWriteLineて、改行が続くテキスト メッセージを送信します。

于 2012-04-12T23:46:58.743 に答える