Sending large image through TCPClient c#

I have the following code to send a picture to a receiving application

public static void sendFile(string file, string ip)
    {

        using (TcpClient client = new TcpClient())
        {
            client.Connect(IPAddress.Parse(ip), 44451);
            //Console.WriteLine(ip);
            NetworkStream nwStream = client.GetStream();

            MemoryStream ms = new MemoryStream();
            Image x = Image.FromFile(file);
            x.Save(ms, x.RawFormat);

            byte[] bytesToSend = ms.ToArray();

            nwStream.Write(bytesToSend, 0, bytesToSend.Length);
            nwStream.Flush();
            client.Close();
        }
    }

and I'm receiving the file on the other end with this

            NetworkStream nwStream = clientCopy.GetStream();
        byte[] buffer = new byte[clientCopy.ReceiveBufferSize];


        //---read incoming stream---
        int bytesRead = nwStream.Read(buffer, 0, clientCopy.ReceiveBufferSize);


MemoryStream ms = new MemoryStream(buffer);
            Image returnImage = Image.FromStream(ms);
            //ms.Flush();
            //ms.Close();
            String path;

            if (!Directory.Exists(path = @"C:\Users\acer\AppData\Roaming\test"))
            {
                Directory.CreateDirectory(@"C:\Users\acer\AppData\Roaming\test");
            }

            string format;
            if (ImageFormat.Jpeg.Equals(returnImage.RawFormat))
            {
                format = ".jpg";
            }
            else if (ImageFormat.Png.Equals(returnImage.RawFormat))
            {
                format = ".png";
            }
            else
            {
                format = ".jpg";
            }

            returnImage.Save(@"C:\Users\acer\AppData\Roaming\test\default_pic" + format, returnImage.RawFormat);

If i'm sending a picture that is small (around <20kb) the file is received 100% on the other end but if I send a file around >=100kb, the picture is received but only half of the image is loaded. I'm aware of the approach of reading the stream until all data is read but I don't know how to implement it right.

Thank you

Jon Skeet
people
quotationmark

You're only calling Read once, which certainly isn't guaranteed to read all the bytes. You could either loop, calling Read and copying the relevant number of bytes on each iteration, or you could use Stream.CopyTo:

var imageStream = new MemoryStream();
nwStream.CopyTo(imageStream);
// Rewind so that anything reading the data will read from the start
imageStream.Position = 0;

... or you could just read the image straight from the network stream:

// No need for another stream...
Image returnImage = Image.FromStream(nwStream);

(It's possible that would fail due to the stream being non-seekable... in which case using CopyTo as above would be the simplest option.)

people

See more on this question at Stackoverflow