3

これはこのフォーラムに投稿された最初の質問であり、私は c# の世界の初心者なので、これは私にとってはエキサイティングなことですが、ソケットを介して大量のデータを送信する際にいくつかの問題に直面しているため、これは詳細です私の問題について:

TCP ソケットを介して 5 Mo のバイナリ イメージを送信しています。受信側で結果を保存しています (受信したデータ)。1.5 Mo のみを取得しています ==> データが失われました (元のファイルと結果のファイルを比較しましたそして、それは私に欠けている部分を示しました)これは私が使用するコードです:

private void senduimage_Click(object sender, EventArgs e)
{
    if (!user.clientSocket_NewSocket.Connected)
    {
        Socket clientSocket_NewSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        user.clientSocket_NewSocket = clientSocket_NewSocket;
        System.IAsyncResult _NewSocket = user.clientSocket_NewSocket.BeginConnect(ip_address, NewSocket.Transceiver_TCP_Port, null, null);
        bool successNewSocket = _NewSocket.AsyncWaitHandle.WaitOne(2000, true);
     }
     byte[] outStream = System.Text.Encoding.ASCII.GetBytes(Uimage_Data);
     user.clientSocket_NewSocket.Send(outStream);
 }

フォーラムでは、データをチャンクに分割するように言われていますが、これは解決策ですか? もしそうなら、どうすればこれを行うことができますか?

4

4 に答える 4

2

さまざまな解決策がたくさんありますが、通常はチャンクが良い解決策です。これをやみくもに行い、一時バッファをいっぱいにしてから、任意のトークンにヒットするか、バッファが完全にいっぱいにならなくなるまでステートフル バッファに入れるか、またはtcpメッセージごとに何らかの契約に従うことができます(メッセージは受信するデータ全体です)。

ある種のコントラクトを行うことを検討している場合は、メッセージの最初の N バイトが記述子であり、必要に応じて大きくしたり小さくしたりできますが、一時バッファーはこのサイズを事前に読み取るだけですストリームから。

典型的なヘッダーは次のようなものです。

public struct StreamHeader // 5 bytes
{
   public byte MessageType {get;set;} // 1 byte
   public int MessageSize {get;set;}  // 4 bytes
}

したがって、十分に小さい場合はメッセージ全体のサイズを一時バッファーに割り当ててすべて読み取るか、大きすぎると判断した場合はそれをセクションに分割し、受信した合計バイト数が MessageSize と一致するまで読み取りを続けます。ヘッダー構造の一部。

于 2012-10-23T09:00:21.117 に答える
0

おそらく、C# でのソケットの使用に関するドキュメントを読んでいないでしょう。( http://msdn.microsoft.com/en-us/library/ms145160.aspx )

内部バッファは、メソッドを送信するために提供したすべてのデータを保存できません。問題の可能な解決策は、データをチャンクに分割すると言ったようなものです。

int totalBytesToSend = outstream.length;     int bytesSend = 0;
while(bytesSend < totalBytesToSend )
    bytesSend+= user.clientSocket_NewSocket.Send(outStream, bytesSend, totalBytesToSend - bytesSend,...);
于 2012-10-23T08:59:43.747 に答える
0

あなたの問題の 1 つは、あなたが に電話していないことだと思いますEndConnect。MSDN ドキュメントから:

非同期の BeginConnect 操作は、EndConnect メソッドを呼び出して完了する必要があります。

また、待機:-

bool successNewSocket = _NewSocket.AsyncWaitHandle.WaitOne(2000, true);

イベントをシグナル状態に設定するものは何もないため、おそらく常に false です。通常、関数にコールバック関数を指定し、コールバックBeginConnectで呼び出しEndConnectてイベントの状態をシグナル状態に設定します。この MSDN ページのサンプル コードを参照してください。

アップデート

別の問題があると思います:-

byte[] outStream = System.Text.Encoding.ASCII.GetBytes(Uimage_Data);

Uimage_Data のタイプはわかりませんが、ASCII に変換する必要はないと思います。データ内のゼロは、データ バイト (または 26 またはその他の ASCII コード) の終わりを示す場合があります。ポイントは、エンコード処理によってデータが変更される可能性が高いということです。

Uimage_Dataオブジェクトのタイプを指定できますか?

于 2012-10-23T09:12:53.780 に答える