2015-09-06 123 views
-1
public void SendFile(string remoteHostIP, int remoteHostPort, string longFileName, string shortFileName) 
{ 
    byte[] fileNameByte = Encoding.ASCII.GetBytes(shortFileName); 
    byte[] fileData = File.ReadAllBytes(longFileName); 
    byte[] clientData = new byte[4 + fileNameByte.Length + fileData.Length]; 
    byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length); 
    fileNameLen.CopyTo(clientData, 0); 
    fileNameByte.CopyTo(clientData, 4); 
    fileData.CopyTo(clientData, 4 + fileNameByte.Length); 
    TcpClient clientSocket = new TcpClient(remoteHostIP, remoteHostPort); 
    NetworkStream networkStream = clientSocket.GetStream(); 
    networkStream.Write(clientData, 0, clientData.GetLength(0)); 
    networkStream.Close();  
} 

可以使用此函数发送1GB文件,因为我现在尝试发送的最大文件大小只有最多400MB。更多的是会导致'System.OutOfMemoryException'错误。 当我使用另一种方法将文件拆分成几个部分,但服务器端不能连续接收部分,只能接收其中一个部分。C#如何使用TCP客户端发送1GB文件

private void splitBigFile(string FileInputPath, byte[] inputArray) 
    { 
     int port = 1113; 

     double partSize = 104852000; 
     int partSize2 = 104852000; 

     string FolderOutputPath = "C:\\Users\\xx\\Desktop\\testing split"; 
     string currPartPath; 
     string shortNameSplit; 

     FileStream fileStream = new FileStream(FileInputPath, FileMode.Open); 
     FileInfo fiSource = new FileInfo(txtFile.Text); 
     double sourceLength = fiSource.Length; 

     partNum = (int)Math.Ceiling((double)(sourceLength/partSize)); 

     for (int i = 0; i < partNum; i++) 
     { 
      if (i == (partNum - 1)) 
      { 
       partSize2 = (int)fiSource.Length - (i * 104852000); 
      } 

      currPartPath = FolderOutputPath + "\\" + fiSource.Name + "." + String.Format(@"{0:D4}", i) + ".part"; 
      shortNameSplit = fiSource.Name + "." + String.Format(@"{0:D4}", i) + ".part"; 

      byte[] fileNameByte = Encoding.ASCII.GetBytes(shortNameSplit); 

      byte[] readStream = new byte[partSize2]; 

      byte[] concateFile = new byte[5 + fileNameByte.Length]; 

      int ipSend = ((partNum - 1 - i) << 1); 
      ipSend |= 0; // for differentiate ip or file 
      byte[] byteSend = new byte[1]; 
      byteSend[0] = (byte)ipSend; 

      fileStream.Read(readStream, 0, partSize2); 
      byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length); 

      byteSend.CopyTo(concateFile, 0); 
      fileNameLen.CopyTo(concateFile, 1); 
      fileNameByte.CopyTo(concateFile, 5); 
      concateFile.CopyTo(inputArray, 0); 
      readStream.CopyTo(inputArray, concateFile.Length); 
      string ipAddress = "192.168.43.67"; 
      int sendport = 1113; 
      //Task.Factory.StartNew(() => SendBigFileSize(ipAddress, sendport, inputArray[i])); 
      Array.Clear(readStream, 0, readStream.Length); 
      Array.Clear(fileNameLen, 0, fileNameLen.Length); 
      Array.Clear(fileNameByte, 0, fileNameByte.Length); 
      Array.Clear(byteSend, 0, byteSend.Length); 
      Array.Clear(byteSend, 0, byteSend.Length); 
     } 
     fileStream.Close(); 
    } 
+3

一次一个块.. –

+0

但我尝试了许多方式,我分裂的文件的一部分,在接收端只能接收一次,虽然客户端仍然继续发送。 – ht9876

+0

我没有看到你尝试任何方式。 – Blindy

回答

2

当然,只是不一次。一次发送块。

此外,最大TCP数据包大小为64k,MTU为1500字节。你的巨大缓冲区也正在分裂,但你正在使用大量的内存。而是从文件中每次读取32MB(安全HDD I/O缓冲区大小)并发送它,然后读取下一位。

+0

是否有任何方法或样本用于发送块? – ht9876

+0

'while'循环和'FileStream.Read'。 – Blindy

+0

......即使是从FileStream到NetworkStream的一个简单的Stream.CopyTo也能很好地完成这项工作。 'Stream.CopyToAsync'的奖励积分:-) –