Search code examples
c#socketsxamarintransfer

How to receive large file over networkstream c#?


Im connecting 2 devices over TCPClient and TCPListener and im sending just a string for now and its all working:

ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes("Hello Server!");
clientStream.Write(buffer, 0 , buffer.Length);
clientStream.Flush();

and then

bytesRead = clientStream.Read(message, 0, 4096);
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine("Mensageee"+ encoder.GetString(message, 0, bytesRead));

But now i need to send a large file over it like 10mb or maybe more so should i use this?

 string doc = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        byte[] file = File.ReadAllBytes(doc + filedir)
        byte[] fileBuffer = new byte[file.Length];
        TcpClient clientSocket = new TcpClient(ip, port);
        NetworkStream networkStream = clientSocket.GetStream();
        networkStream.Write(file.ToArray(), 0, fileBuffer.GetLength(0));
        networkStream.Close();

And how should i receive all this file and then save it somewhere? Any help is welcome thanks o/


Solution

  • The short answer is, you send a byte[] multiple times...

    Essentially, you will need to fill a buffer ('byte[]') with a subset of the file:

    int count = fileIO.Read(buffer, 0, buffer.Length);
    

    And then send the buffer over the socket:

    clientSocket.Send(buffer, 0, count);
    

    Just do these two processes until you have sent the entire file... (Which will be when count <= 0) However, the server has to know how many bytes to read... so we should start out by sending a Int64 with the file's length.

    What we have so far...

    using (var fileIO = File.OpenRead(@"C:\temp\fake.bin"))
    using(var clientSocket = new System.Net.Sockets.TcpClient(ip, port).GetStream())
    {
      // Send Length (Int64)
      clientSocket.Write(BitConverter.GetBytes(fileIO.Length, 0, 8));
    
      var buffer = new byte[1024 * 8];
      int count;
      while ((count = fileIO.Read(buffer, 0, buffer.Length)) > 0)
        clientSocket.Write(buffer, 0, count);
    }
    

    Server Side

    Int64 bytesReceived = 0;
    int count;
    var buffer = new byte[1024*8];
    
    // Read length - Int64
    clientStream.Read(buffer, 0, 8);
    Int64 numberOfBytes = BitConverter.ToInt64(buffer, 0);
    
    using(var fileIO = File.Create("@c:\some\path"))
      while(bytesReceived < numberOfBytes && (count = clientStream.Read(buffer, 0, buffer.Length)) > 0)
      {
        fileIO.Write(buffer, 0, count);
        bytesReceived += count;
      }