How can I show the current speed of download/upload with tcp client?

Viewed 69

I'm creating a file transfer app which works with TcpListener and TcpClient. My app works perfectly, I'm just wondering how I can show the download/upload speed while data is transferring. I also want the app to show how many MBs are downloaded or uploaded.

Server code:

  IPAddress ip = IPAddress.Parse("192.168.1.2");
        int port = 9999;

        TcpListener server = new TcpListener(ip, port);
        server.Start();

        Console.WriteLine("Waiting for client...");

        TcpClient tcpClient = server.AcceptTcpClient();

        Console.WriteLine("Client connected!");

        NetworkStream networkStream = tcpClient.GetStream();
        string path = string.Empty;
        string fileName = string.Empty;

        Console.Write("File:");
        path = Console.ReadLine();

        fileName = Path.GetFileName(path);

        byte[] bytes = File.ReadAllBytes(path);

        BinaryWriter bwFileName = new BinaryWriter(networkStream);
        bwFileName.Write(fileName);

        BinaryWriter bw = new BinaryWriter(networkStream);
        bw.Write(bytes.Length);

        networkStream.Write(bytes, 0, bytes.Length);

        Console.ReadLine();

Client code:

IPAddress ip = IPAddress.Parse("192.168.1.2");
        int port = 9999;

        TcpClient client = new TcpClient();
        client.Connect(ip, port);

        while (true)
        {
            NetworkStream networkStream = client.GetStream();

            int byteLenght;
            string fileName = string.Empty;

            BinaryReader brFilename = new BinaryReader(networkStream);
            fileName = brFilename.ReadString();

            BinaryReader br = new BinaryReader(networkStream);
            byteLenght = br.ReadInt32();

            byte[] bytes = new byte[byteLenght];

            networkStream.Read(bytes, 0, bytes.Length);

            File.WriteAllBytes("C:\\Users\\XANDRO\\Desktop\\client\\" + fileName,bytes);
             
            break;
        }
        Console.ReadLine();
1 Answers

the general approach would be to split the download/upload into chunks. I.e. instead of writing the entire byte array in one go, write chunks using the offset/length parameters.

This gives an opportunity to measure the time and report the progress after each chunk. You might also consider using a file stream and write/read chunks from this as well. Since this will limit memory usage.

Edit: Example code:

    public static void Copy(Stream from, Stream to, IProgress<int> progress, int bufferSize = 4096)
    {
        var bytesCopied = 0;
        var buffer = new byte[bufferSize];
        int bytesRead;
        do
        {
            bytesRead = from.Read(buffer, 0, buffer.Length);
            to.Write(buffer, 0, bytesRead);
            bytesCopied += bytesRead;
            progress.Report(bytesCopied);
        } while (bytesRead != 0);
    }
Related