AndroidはTCPのブレークポイントアップロードを実現し、バックグラウンドC钻サービス受信を行う。


端末が大きいファイルのアップロードを実現するのはずっと難しい技術です。バックエンドとフロントエンドの相互作用、安定性と流量の大きさに関連しています。そして、原理を実現するために、すべての人が自分の考えを持っています。バックエンドの主流はHttpで実現します。しかし、安定性は保証できません。一旦切断したら、継続できません。だからもう一つの流行のやり方を採用して、TCPは大きいファイルをアップロードします。 
インターネットでいくつかの資料を検索しましたが、ほとんどは断点ダウンロードで、その後は単独のC〓〓端のアップロード受信、あるいはHTTPの、あるいはandroid端だけです。任務がきついので、先に探した優先案はもちろんHttpが先にファイルアップロードを実現します。端末はPost方法を採用して、ファイルを直接後端に伝えて、後端はFileを通じて獲得します。 
android端: 

RequestParams params = new RequestParams();
 File file = getTempFile();//      
  try {
   params.put("file", file);
  } catch (FileNotFoundException e1) {
   e1.printStackTrace();
  }
  AsyncHttpUtil.post(URL + "/UpLoad", params, new JsonHttpResponseHandler() {
……

バックエンド:
 var file=Request.Files[file]
  file.SaveAs(up FileName);
他にもっと良い処理方法があります。ファイル形式を通じて、流し込むこともできます。ネットがいい場合は大丈夫ですが、ネットは後になって、いつも途中でアップロードしたり、複数のクライアントにアップロードしたりして、接続できない場合があります。大きなファイルに対しては非常に不安定です。だから、TCPプロトコルファイルを開発して、断点アップロードします。
Httpの断点アップロードを実現したネットユーザーもいます。大きなファイルがだめなら、ファイルを小さいファイルに分割してアップロードします。純NETの主な方法: 
アップロード: 

 bool result = true;
   long cruuent = 0;

   FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
   BinaryReader bReader = new BinaryReader(fStream); 
   
   //      ,       100    
   long length = 100;

   fileName = fileName.Substring(fileName.LastIndexOf('\\') + 1);

   #region       
   try
   {

    
    byte[] data; 
    #region       
    for (; cruuent <= length; cruuent = cruuent + byteCount)
    {
     if (cruuent + byteCount > length)
     {
      data = new byte[Convert.ToInt64((length - cruuent))];
      bReader.Read(data, 0, Convert.ToInt32((length - cruuent)));
     }
     else
     {
      data = new byte[byteCount];
      bReader.Read(data, 0, byteCount);
     }
     try
     {
      Hashtable parms = new Hashtable();
      parms.Add("fileName", fileName);
      parms.Add("npos", cruuent.ToString());

      byte[] byRemoteInfo = PostData(serverPath + "UpLoadServer.aspx", data, parms);

     }
     catch (Exception ex)
     {
      msg = ex.ToString();
      result = false;
      break;
     }
    #endregion
    }
   }
   catch (Exception ex)
   {
    msg = ex.ToString();
    result = false;
   }
   finally
   {
    bReader.Close();
    fStream.Close();

   }

   GC.Collect();

まずファイルを小流に分割して、nposはブレークポイントの位置、すなわちアップロード済みのサイズにして、それから循環的にすべてのパケットをアップロードします。
バックグラウンド受信: 

 /// <summary>
 ///     ( URL        、    ,            )
 ///         ,      0,         ,         
 /// </summary>
 public void SaveUpLoadFile()
 {

  string fileName = Request.Params["fileName"];
  long npos = Convert.ToInt64(Request.Params["npos"]);

  int upLoadLength = Convert.ToInt32(Request.InputStream.Length);
  
  string path = Server.MapPath("/UpLoadServer");
  fileName = path + "//UpLoad//" + fileName;

  FileStream fStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
  //    
  fStream.Seek(npos, SeekOrigin.Begin);

  //             
  BinaryReader bReader = new BinaryReader(Request.InputStream);
  try
  {
   byte[] data = new byte[upLoadLength];
   bReader.Read(data, 0, upLoadLength);
   fStream.Write(data, 0, upLoadLength);
  }
  catch
  {
   //TODO       
  }
  finally
  {
   //   
   fStream.Close();
   bReader.Close();
  }
 }

ポイントはfStream.Seek(npos,SeekOrigin.Begin)です。ブレークポイント位置から保存を受信します。
興味のある人は自分で実現できます。  
クライアントTCPのアップロードについては、バックグラウンドTCPの受信について説明します。ローカルファイル名をandroid端末で読み、ファイルサイズをサーバにアップロードします。(ファイル名はグローバル一意でなければなりません。)サーバはファイル名に基づいて、アップロードしたかどうかを確認します。アップロードした場合、ファイルサイズである断点位置を端末に伝えます。端末が受信したら、断点位置を保存します。断線位置からファイルを読み込み、断続的にアップロードします。全部完了するまで。アップロードしていない場合はサーバがキャッシュファイルを作成して受信します。 
コードAndroidを見てください。 

String head = "Length=" + uploadFile.length() + ";filename=" + filename

 Socket socket = new Socket("192.168.0.123", 7080);
     OutputStream outStream = socket.getOutputStream();
     outStream.write(head.getBytes());//  

     PushbackInputStream inStream = new PushbackInputStream(socket.getInputStream());
     String response = StreamTool.readLine(inStream);//  
     String[] items = response.split(";");

 final String position = items[0].substring(items[0].indexOf("=") + 1);//    
      final String serviceurl = items[1].substring(items[1].indexOf("=") + 1);//        

RandomAccessFile fileOutStream = new RandomAccessFile(uploadFile, "r");
      fileOutStream.seek(Integer.valueOf(position));//           
      byte[] buffer = new byte[1024];
      int len = -1;
      int length = Integer.valueOf(position);//       ,      
      while ( (len = fileOutStream.read(buffer)) != -1) {
       outStream.write(buffer, 0, len);
       length += len;
       Message msg = new Message();
       msg.getData().putInt("size", length);
       //               handler.sendMessage(msg);

      } if (length == uploadFile.length()) {//    ,       } fileOutStream.close(); outStream.close(); inStream.close(); socket.close(); 

バックエンド処理: 

 private static TcpListener listener;//     
 IPAddress ipHost = IPAddress.Any;
 listener = new TcpListener(ipHost, 7080);
     listener.Start();//    

 Socket remoteSocketClient = listener.AcceptSocket();
     device = new Device(remoteSocketClient);
//         
     threaddev = new Thread(new ThreadStart(device.Scan));
     device.curentThread = threaddev;
     threaddev.IsBackground = true;
     threaddev.Start();

Scan処理方法:

string[] items = strGetContent.Split(';');
     string filelength = items[0].Substring(items[0].IndexOf("=") + 1);
     string filename = items[1].Substring(items[1].IndexOf("=") + 1);
 //        
       filePath = Path.Combine(directoryPath, filename);
//    
      long position = 0;
      if (File.Exists(filePath))
      {
       using (FileStream reader = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
       {
        position = reader.Length;
       }
      }
//    
 response = "position=" + position + ";serviceurl=" + dirPath + "/" + filename) ;
      

      //              ,          :;position=0 
      //serviceurl            /PlayFiles/video/2016/07/04/1141142221.mp4
      bufferSend = Encoding.UTF8.GetBytes(response);
      remoteSocketClient.Send(bufferSend);

その後、継続内容を処理します。

//      
      byte[] buffer = new byte[BufferSize];
      int received = 0;
      long receive, length = long.Parse(filelength);
      FileInfo file = new FileInfo(filePath);
      using (FileStream writer = file.Open(file.Exists ? FileMode.Append : FileMode.CreateNew, FileAccess.Write, FileShare.None))
      {
       receive = writer.Length;
       while (receive < length)
       {
        if ((received = remoteSocketClient.Receive(buffer)) == 0)
        {
         Program.MessageAdd(" IP【" + remoteSocketClient.RemoteEndPoint.ToString() + "】    !");
         break;
        }
        writer.Write(buffer, 0, received);
        writer.Flush();
        receive += (long)received;
       }

      }

if (receive == length)
      {
       Program.MessageAdd(" IP【" + remoteSocketClient.RemoteEndPoint.ToString() + "】  " + filename + "  !");
}
主な原理はやはり断線位置からアップロードと受信です。 
ここでは、最も主要なコード機能を説明しただけでなく、端末が進捗を表示するため、後端のファイルの保存が間違っていませんか?
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。