C# high-performance large-capacity SOCKET concurrency (9): breakpoint resume

upload resume

Breakpoint resuming is mainly used to upload or download files. The general practice is that when uploading starts, the server returns the size that has been uploaded last time. If the uploading is completed, it returns -1; when the download starts, the client reports that the local Download size, the server sends data according to the location information, so the upload and download protocols need to carry the Size size, such as our protocol format.

Upload starts:

Client -> Server

{

[Request]

Command=Upload

Dir=Dir #Directory, full path name

FileName=FileName #File name (excluding path)

}

Server -> Client

{

[Response]

Command=Upload

Code= Error Code #Error code

Message=Message #If there is an error, return the error description information

FileSize=FileSize #The size of the uploaded file for continued upload

}

Therefore, when receiving the upload request from the client, it is necessary to deliver the file address that the server received last time:

[csharp] view plain copy
print ?
  1. public bool  DoUpload()   
  2. {  
  3.     string dirName = "";  
  4.     string fileName = "";  
  5.     if (m_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName) & m_incomingDataParser.GetValue(ProtocolKey.FileName, ref fileName))  
  6.     {  
  7.         if (dirName == "")  
  8.             dirName = Program.FileDirectory;  
  9.         else  
  10.             dirName = Path.Combine(Program.FileDirectory, dirName);  
  11.         fileName = Path.Combine(dirName, fileName);  
  12.         Program.Logger.Info("Start upload file: " + fileName);  
  13.         if  (m_fileStream !=  null //Close the last transferred file  
  14.         {  
  15.             m_fileStream.Close();  
  16.             m_fileStream = null;  
  17.             m_fileName = "";  
  18.         }  
  19.         if (File.Exists(fileName))  
  20.         {  
  21.             if  (!CheckFileInUse(fileName))  //Check if the file is in use  
  22.             {  
  23.                 m_fileName = fileName;  
  24.                 m_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);  
  25.                 m_fileStream.Position = m_fileStream.Length;  //The file is moved to the end  
  26.                 m_outgoingDataAssembler.AddSuccess();  
  27.                 m_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, m_fileStream.Length);  
  28.             }  
  29.             else  
  30.             {  
  31.                 m_outgoingDataAssembler.AddFailure(ProtocolCode.FileIsInUse, "");  
  32.                 Program.Logger.Error("Start upload file error, file is in use: " + fileName);  
  33.             }  
  34.         }  
  35.         else  
  36.         {  
  37.             m_fileName = fileName;  
  38.             m_fileStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);  
  39.             m_fileStream.Position = m_fileStream.Length;  //The file is moved to the end  
  40.             m_outgoingDataAssembler.AddSuccess();  
  41.             m_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, m_fileStream.Length);  
  42.         }  
  43.     }  
  44.     else  
  45.         m_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");  
  46.     return  DoSendResult ();  
  47. }  
        public bool DoUpload()
        {
            string dirName = "";
            string fileName = "";
            if (m_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName) & m_incomingDataParser.GetValue(ProtocolKey.FileName, ref fileName))
            {
                if (dirName == "")
                    dirName = Program.FileDirectory;
                else
                    dirName = Path.Combine(Program.FileDirectory, dirName);
                fileName = Path.Combine(dirName, fileName);
                Program.Logger.Info("Start upload file: " + fileName);
                if (m_fileStream != null) //Close the last transferred file
                {
                    m_fileStream.Close();
                    m_fileStream = null;
                    m_fileName = "";
                }
                if (File.Exists(fileName))
                {
                    if (!CheckFileInUse(fileName)) //Check if the file is in use
                    {
                        m_fileName = fileName;
                        m_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);
                        m_fileStream.Position = m_fileStream.Length; //The file is moved to the end
                        m_outgoingDataAssembler.AddSuccess();
                        m_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, m_fileStream.Length);
                    }
                    else
                    {
                        m_outgoingDataAssembler.AddFailure(ProtocolCode.FileIsInUse, "");
                        Program.Logger.Error("Start upload file error, file is in use: " + fileName);
                    }
                }
                else
                {
                    m_fileName = fileName;
                    m_fileStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    m_fileStream.Position = m_fileStream.Length; //The file is moved to the end
                    m_outgoingDataAssembler.AddSuccess();
                    m_outgoingDataAssembler.AddValue(ProtocolKey.FileSize, m_fileStream.Length);
                }
            }
            else
                m_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");
            return DoSendResult ();
        }

Download resume
Download starts:

Client -> Server

{

[Request]

Command=Download

Dir=Dir #Directory, full path name

FileName=FileName #File name (excluding path)

FileSize=FileSize #Client local file size for resuming the upload

PacketSize=PacketSize #Send data packet size, in KB, for speed test

}

Server -> Client

{

[Response]

Command= Download

Code= Error Code #Error code

Message=Message #If there is an error, return the error description information

}

[csharp] view plain copy
print ?
  1. publicbool DoDownload()   
  2. {  
  3.     string dirName = "";  
  4.     string fileName = "";  
  5.     Int64 fileSize = 0;  
  6.     int packetSize = 0;  
  7.     if (m_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName) & m_incomingDataParser.GetValue(ProtocolKey.FileName, ref fileName)  
  8.         & m_incomingDataParser.GetValue(ProtocolKey.FileSize, ref fileSize) & m_incomingDataParser.GetValue(ProtocolKey.PacketSize, ref packetSize))  
  9.     {  
  10.         if (dirName == "")  
  11.             dirName = Program.FileDirectory;  
  12.         else  
  13.             dirName = Path.Combine(Program.FileDirectory, dirName);  
  14.         fileName = Path.Combine(dirName, fileName);  
  15.         Program.Logger.Info("Start download file: " + fileName);  
  16.         if  (m_fileStream !=  null //Close the last transferred file  
  17.         {  
  18.             m_fileStream.Close();  
  19.             m_fileStream = null;  
  20.             m_fileName = "";  
  21.             m_sendFile = false;  
  22.         }  
  23.         if (File.Exists(fileName))  
  24.         {  
  25.             if  (!CheckFileInUse(fileName))  //Check if the file is in use  
  26.             {  
  27.                 m_fileName = fileName;  
  28.                 m_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);  
  29.                 m_fileStream.Position = fileSize;  //The file is moved to the last download position  
  30.                 m_outgoingDataAssembler.AddSuccess();  
  31.                 m_sendFile = true;  
  32.                 m_packetSize = packetSize;  
  33.             }  
  34.             else  
  35.             {  
  36.                 m_outgoingDataAssembler.AddFailure(ProtocolCode.FileIsInUse, "");  
  37.                 Program.Logger.Error("Start download file error, file is in use: " + fileName);  
  38.             }  
  39.         }  
  40.         else  
  41.         {  
  42.             m_outgoingDataAssembler.AddFailure(ProtocolCode.FileNotExist, "");  
  43.         }  
  44.     }  
  45.     else  
  46.         m_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");  
  47.     return  DoSendResult ();  
  48. }  
        public bool DoDownload()
        {
            string dirName = "";
            string fileName = "";
            Int64 fileSize = 0;
            int packetSize = 0;
            if (m_incomingDataParser.GetValue(ProtocolKey.DirName, ref dirName) & m_incomingDataParser.GetValue(ProtocolKey.FileName, ref fileName)
                & m_incomingDataParser.GetValue(ProtocolKey.FileSize, ref fileSize) & m_incomingDataParser.GetValue(ProtocolKey.PacketSize, ref packetSize))
            {
                if (dirName == "")
                    dirName = Program.FileDirectory;
                else
                    dirName = Path.Combine(Program.FileDirectory, dirName);
                fileName = Path.Combine(dirName, fileName);
                Program.Logger.Info("Start download file: " + fileName);
                if (m_fileStream != null) //Close the last transferred file
                {
                    m_fileStream.Close();
                    m_fileStream = null;
                    m_fileName = "";
                    m_sendFile = false;
                }
                if (File.Exists(fileName))
                {
                    if (!CheckFileInUse(fileName)) //Check if the file is in use
                    {
                        m_fileName = fileName;
                        m_fileStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite);
                        m_fileStream.Position = fileSize; //The file is moved to the last download position
                        m_outgoingDataAssembler.AddSuccess();
                        m_sendFile = true;
                        m_packetSize = packetSize;
                    }
                    else
                    {
                        m_outgoingDataAssembler.AddFailure(ProtocolCode.FileIsInUse, "");
                        Program.Logger.Error("Start download file error, file is in use: " + fileName);
                    }
                }
                else
                {
                    m_outgoingDataAssembler.AddFailure(ProtocolCode.FileNotExist, "");
                }
            }
            else
                m_outgoingDataAssembler.AddFailure(ProtocolCode.ParameterError, "");
            return DoSendResult ();
        }

Multi-threaded concurrent download

One application of resumable upload is concurrent download. The method is that the client starts multiple threads and requests the same file concurrently. After all the downloads are completed, each data block is merged into one file. Neither the server nor the client protocol needs to be modified, only the download logic needs to be changed.

Multi-threaded concurrent upload

This needs to define communication to support this logic, mainly because the server needs to provide protocol logic for merging multiple data files into one file.

DEMO download address: http://download.csdn.net/detail/sqldebug_fan/7467745
Disclaimer: This code is only to demonstrate C# complete port programming, only for learning and research, not for commercial purposes. The level is limited, and C# is also a beginner. Errors are inevitable. Corrections and guidance are welcome. Email address: [email protected].

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325993152&siteId=291194637