简体   繁体   中英

C# tcp socket client server transfer multiple files problem

I have 2 applications, one is server-app and the other is client-app. both are on same computer.Client has one button. When this button is clicked, client starts downloading files from server. The problem is, sometimes client side received all files successfully, but sometimes client side only received the 1st file then stop transferring. Is there something wrong with the code below? could any1 show me where I'm wrong? I'm just new to coding like this. help is much appreciated. Thanks in advance. Here is the code:

When user click a button on client, client will send a request download files from server:

//client side
sendRequest("requestFiles ");

Server will prepare files for client to download after receive token 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;
}

For each file needs to upload, server will send a token CommitRequest with details of the file (name, size) When client receives CommitRequest:

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

Method downloadFileFromServer at client:

//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);
    }
}

Method clientDownloadFromServer at server side:

//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();
    }
}

Issue is related to treating receiving bytes as file bytes or token bytes. Your client code is trying to read bytes that are equal to buffer size. Server sends "CommitRequest" token and file bytes one after another. So let's say first file size is of 1200 bytes. Server will send these 1200 bytes followed by "CommitRequest" for second file followed by second file bytes. Now, client would read 1024 bytes of first file. And then it would read next 1024 bytes - but these bytes will contain remaining 176 bytes of first file, "CommitRequest" response from server and then first few bytes of second file. Your client code only takes first 176 bytes and ignoring next bytes that would have data for next file.

You can solve the issue in two ways - either by making sure that remaining bytes would be processed (this can be tricky because remaining bytes may have "CommitRequest" response partially) or re-structuring your solution so that each file transfer will be initiated only after client request.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM