1

重複の可能性:
TcpClient がデータを送信し、ネットワークを介してデータを受信する
TcpClient 応答が完全に読み取られるまでループする

TCP 経由でサーバーからクライアントにファイルを送信しようとしています。

サーバー側コード、送信ファイル:

NetworkStream netStream = client.GetStream();
FileStream fs = new FileStream("usb.exe",FileMode.Open, FileAccess.Read);
byte[] data = new byte[fs.Length];
fs.Read(data,0, data.Length);
fs.Flush();
fs.Close();

netStream.Write(data, 0, data.Length);
netStream.Flush();

クライアント側コード、受信ファイル:

FileStream str = new FileStream("usb.exe", FileMode.Create, FileAccess.Write);
byte[] data = new byte[1024];

while ((dataCitit = netStream.Read(data,0, data.Length)) > 0)
    {
         Thread.Sleep(25);
         Application.DoEvents();

         str.Write(data, 0, dataCitit);
         totalbytes += dataCitit;                      
    }
str.Close();

誰かが私が間違っているところを指摘できますか?

ファイルには 1036 kb があり、1032 kb のみを送信してスタックし、クライアント側の while ループから抜け出せません。

また、サーバーを閉じてすぐに開くと、最後のバイトが送信され、ファイルが完全に送信されます。(このファイルは完全に開きます)

すべてのバイトを送信しないのはサーバー側の問題だと思いますが、なぜ、どこで...

4

1 に答える 1

6

さて、これはサーバー側のコードの問題です。

fs.Read(data,0, data.Length);

によって返される値を無視していますRead絶対にしないでください。あなたFileStreamおそらく大丈夫ですが、個人的にはとにかく信用しません。.NET 4 を使用している場合は、とにかくこれを行う必要はありません。使用するだけStream.CopyToです。

クライアント側のコードでは、最初の最大の問題は、これらすべてを UI スレッドで実行していることです。これはひどい考えです。ネットワークに問題があると、Read通話がブロックされるため、UI がフリーズします。

繰り返しますが、単に使用Stream.CopyToしますが、バックグラウンド スレッドで実行してください。

さらに、これらすべてのケースでusing、ストリームにステートメントを使用して、何が起こってもストリームをきれいに閉じるようにします。

それはすべて一般的な衛生状態です。さて、なぜあなたがぶら下がっているのか...

...サーバー側でネットワークストリームを閉じていません。したがって、クライアント側でストリームの最後に到達することはありません。単一のファイルに対してのみ接続を使用する必要がある場合、答えは簡単です。サーバー側で接続を閉じるだけです。

ただし、複数のファイルに同じ接続を使用する必要がある場合は、さらにプロトコルが必要です。データの終わりを示す何らかの方法が必要です。これを行うには、次の 3 つの一般的な方法があります。

  • データ自体の前にデータの長さを書き込み、次に読み取り側で、最初に長さを読み取り、次にそのバイト数を読み取ります。そうする前にストリームが終了すると失敗します。これには、書き込みを開始する前に、書き込むデータの量を知っている必要があります。
  • 読み取り側で検出できる「データの終わり」マーカーを使用します。マーカーがテキスト自体に表示される場合、マーカーをエスケープする必要があるため、これは一般的に面倒です。
  • 最初のアプローチのバリエーションで、一度に長さがプレフィックスされたチャンクを書き込み、次に「データの終わり」を示す長さゼロのチャンクを書き込みます。これは非常に柔軟ですが、最初のアプローチが実際に機能する場合、明らかに最初のアプローチよりも少し手間がかかります。
于 2012-11-23T07:31:38.190 に答える