0

2 つのアプリケーションがあります。1 つはサーバー アプリで、もう 1 つはクライアント アプリです。どちらも同じコンピュータ上にあります。クライアントにはボタンが 1 つあります。このボタンをクリックすると、クライアントはサーバーからファイルのダウンロードを開始します。問題は、クライアント側がすべてのファイルを正常に受信することがありますが、クライアント側が最初のファイルのみを受信して​​転送を停止することがあります。以下のコードに何か問題がありますか?私が間違っているところを教えてもらえますか?私はこのようなコーディングが初めてです。助けていただければ幸いです。前もって感謝します。コードは次のとおりです。

ユーザーがクライアントのボタンをクリックすると、クライアントはサーバーからファイルをダウンロードする要求を送信します。

//client side
sendRequest("requestFiles ");

サーバーは、トークン requestFiles の受信後にクライアントがダウンロードするファイルを準備します

// server side
if (execmd == "requestFiles")
{
    string[] fList = Directory.GetFiles(folderDir);
    for (int i = 0; i < fList.Length; i++)
    {
        FileInfo fi = new FileInfo(fList[i]);
        string[] mDesc = new string[3];
        mDesc[0] = fi.Name;
        mDesc[1] = fi.Length.ToString();
        mDesc[2] = fi.FullName;
        string fileSend = "CommitRequest " + fi.Name + " " + fi.Length.ToString() + " " + usID + " " + mName;
        sendRequest(fileSend);
        ClientDownloadingFromServer(mDesc[2], mDesc[1], sock);
    }
    sendComment("AllUpDone");
    continue;
}

アップロードが必要なファイルごとに、サーバーはファイルの詳細 (名前、サイズ) を含むトークン CommitRequest を送信します。クライアントが CommitRequest を受信すると、次のようになります。

//client side
if (execmd == "CommitRequest")
{
    //get file name and file size
    downloadFileFromServer(sock);
    continue;
}

クライアントでのメソッド downloadFileFromServer:

//client side
private void downloadMapFromServer(Socket s)
{        
    Socket sock = s;
    //prepare directory rootDir to store file
    System.IO.FileStream fout = new System.IO.FileStream(rootDir + "\\" + fileN, FileMode.Create, FileAccess.Write);
    NetworkStream nfs = new NetworkStream(sock);
    long size = int.Parse(fileS);
    long rby = 0;
    try
    {
        //loop till the Full bytes have been read
        while (rby < size)
        {
            byte[] buffer = new byte[1024];
            //Read from the Network Stream
            int i = nfs.Read(buffer, 0, buffer.Length);
            fout.Write(buffer, 0, (int)i);
            rby = rby + i;
        }
        fout.Close();
    }
    catch (Exception ed)
    {
        Console.WriteLine("A Exception occured in file transfer" + ed.ToString());
        MessageBox.Show(ed.Message);
    }
}

サーバー側の clientDownloadFromServer メソッド:

//server side
void ClientDownloadingFromServer(string fiPath, string fiSize, Socket s)
{
    string parm1 = fiPath;
    string parm2 = fiSize;
    try
    {
        FileInfo ftemp = new FileInfo(parm1);
        long total=ftemp.Length;
        long rdby=0 ;
        int len=0 ;
        byte[] buffed = new byte[1024] ;
        // Open the file requested for download 
        System.IO.FileStream fin = new System.IO.FileStream(parm1,FileMode.Open , FileAccess.Read) ;

        NetworkStream nfs = new NetworkStream(sock) ;

        while(rdby < total && nfs.CanWrite)
        {
             //Read from the File (len contains the number of bytes read)
             len =fin.Read(buffed,0,buffed.Length) ;
             //Write the Bytes on the Socket
             nfs.Write(buffed, 0,len);
             //Increase the bytes Read counter
             rdby=rdby+len ;    
        }
        fin.Close();
    }
}
4

1 に答える 1

0

問題は、受信バイトをファイル バイトまたはトークン バイトとして処理することに関連しています。クライアント コードは、バッファー サイズと等しいバイト数を読み取ろうとしています。サーバーは「CommitRequest」トークンとファイルバイトを次々に送信します。最初のファイル サイズが 1200 バイトだとします。サーバーは、これらの 1200 バイトを送信し、その後に 2 番目のファイルの「CommitRequest」、2 番目のファイル バイトが続きます。ここで、クライアントは最初のファイルの 1024 バイトを読み取ります。そして、次の 1024 バイトを読み取りますが、これらのバイトには、最初のファイルの残りの 176 バイト、サーバーからの「CommitRequest」応答、および 2 番目のファイルの最初の数バイトが含まれます。クライアント コードは最初の 176 バイトのみを使用し、次のファイルのデータを持つ次のバイトを無視します。

この問題は 2 つの方法で解決できます。残りのバイトが処理されることを確認するか (残りのバイトには部分的に "CommitRequest" 応答が含まれている可能性があるため、これは難しい場合があります)、または各ファイル転送のみが開始されるようにソリューションを再構築します。クライアントの要求の後。

于 2010-12-08T10:08:53.940 に答える