none
Best Way to write large data over network stream of TcpClient RRS feed

  • Question

  • We have a requirement to upload large firmware files to printers to upgrade the firmware of the device. The printer device is in the same network as my server, and the size of firmware that we are trying to upload is approximately to 200 - 500 MB. The approach that we have chosen is to load the firmware (.bin file) into Memory stream and write it in chunks over the network using TcpClient.

    Based on the response from the network stream, we are displaying the status of firmware upgrade to the client. Following is the code snippet that we have used for firmware upgrade. I want to know if it is the best approach, as wrong one may harm the device.

    class MyClass
    {
        int port = 9100;
        string _deviceip;
        byte[] m_ReadBuffer = null;
        TcpClient _tcpclient;
        NetworkStream m_NetworkStream;
        static string CRLF = "\r\n";
    
        public event EventHandler<DeviceStatus> onReceiveUpdate;
    
        public async Task<bool> UploadFirmware(Stream _stream)
        {
            bool success = false;
            try
            {
                _tcpclient = new TcpClient();
                _tcpclient.Connect(_deviceip, port);
    
                _stream.Seek(0, SeekOrigin.Begin);
                m_NetworkStream = _tcpclient.GetStream();
                byte[] buffer = new byte[1024];
                m_ReadBuffer = new byte[1024];
                int readcount = 0;
                m_NetworkStream.BeginRead(m_ReadBuffer, 0, m_ReadBuffer.Length,
                                         new AsyncCallback(EndReceive), null);
                await Task.Run(() =>
                {
                    while ((readcount = _stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        m_NetworkStream.Write(buffer, 0, readcount);
                        m_NetworkStream.Flush();
                    }
                });
                success = true;
            }
            catch (Exception ex)
            {
                upgradeStatus = false;
            }
            return success;
        }
    
         private void EndReceive(IAsyncResult ar)
         {
             try
             {
                 int nBytes;
                 nBytes = m_NetworkStream.EndRead(ar);
                 if (nBytes > 0)
                 {
                     string res = Encoding.UTF8.GetString(m_ReadBuffer, 0, nBytes);
                     DeviceStatus status = new DeviceStatus();
    
                     string[] readlines = res.Split(new string[] { CRLF }, 
                                  StringSplitOptions.RemoveEmptyEntries);
                     foreach (string readline in readlines)
                     {
                         if (readline.StartsWith("CODE"))
                         {
                             //read readline string here
                             break;
                         }
                     }
                 }
             }
             catch (ObjectDisposedException ods)
             {
                 return;
             }
             catch (System.IO.IOException ex)
             {
             }
         }
    }

    Any help will be really appreciated.


    Saket Kumar

    Friday, July 1, 2016 8:51 AM

Answers

  • Hi Saket,

    I didn't find any errors in your code. But I suggest you use a TcpListener to test your code before you upgrade the firmware.

    TcpListener server = null;
    try
    {
        // Set the TcpListener on port 12345.
        Int32 port = 12345;
        IPAddress localAddr = IPAddress.Parse("127.0.0.1");
        server = new TcpListener(localAddr, port);
        // Start listening for client requests.
        server.Start();
    
        // Buffer for reading data
        Byte[] bytes = new Byte[1024];
        String data = null;
    
        // Enter the listening loop.
        while (true)
        {
            Console.Write("Waiting for a connection... ");
    
            // Perform a blocking call to accept requests.
            // You could also user server.AcceptSocket() here.
            TcpClient client = server.AcceptTcpClient();
            Console.WriteLine("Connected!");
    
            data = null;
    
            // Get a stream object for reading and writing
            NetworkStream stream = client.GetStream();
    
            int i;
    
            // Loop to receive all the data sent by the client.
            while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
            {
                // Translate data bytes to a ASCII string.
                data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                Console.WriteLine("Received: {0}", data);
            }
    
            // Shutdown and end connection
            client.Close();
        }
    }
    catch (SocketException e)
    {
        Console.WriteLine("SocketException: {0}", e);
    }
    finally
    {
        // Stop listening for new clients.
        server.Stop();
    }
    Best Regards,
    Li Wang

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Monday, July 4, 2016 5:47 AM
    Moderator