C# bandwidth test won't stop

Hello ,
I want to see the resault of the bandwidth-test
but I can’t get it to stop:

 private void button5_Click(object sender, EventArgs e)
        {
            mikrotik.Send("/tool/bandwidth-test");
            mikrotik.Send("=user=" + SpeedUSer);
            mikrotik.Send("=password=" + SpeedPass);
            mikrotik.Send("=address=" + SpeedAdress);
            mikrotik.Send("=duration=2", true);

           foreach (string h in mikrotik.Read())
            {
               textBox21.Text = (h);
            }
        }

when I debug it I can see this as answer

!re=status=connecting=duration=0s=rx-current=0=rx-10-second-average=0=rx-total-average=0=lost-packets=0=random-data=false=direction=receive=rx-size=1500=.section=33

shouldn’t it stop after 2?

Thanks,

It stops after 2 seconds, during which it could collect much more than 2 sections - yours apparently reached at least 33. Each section just groups all data retrieved in one swoop.

e.g. the router may collect f.e. 10 measurements, before giving them all over the API, and meanwhile, another 15 are ready to be given, and so .section=1 has 10 replies, .section=2 has 15 replies, and this continues until 2 seconds have passed.

If you were to f.e. draw a graph based on the data given by the API, you’d want to do the drawing based on the value of “duration”, not based on the value of “.section”.


Or do you mean that after more than 2 seconds, the status is still “connecting”? Yeah… From what I’m seeing, the CLI just hangs as well, unless you manually press “q”. In the case of the API, you’ll need to monitor the replies and check the status for however much time you’re willing to wait for the test to start. Then, call a “/cancel” command to stop it if it goes over too far without starting, or switch to whatever it is you want to do with the data if the status changes.

I disagree with you
because when I run the same command in CLI I can he stop after 5-7 seconds when he is unable to connect (I didn’t have to press “q”)
also when I do connect and give him to work for duration=15 seconds - he quit after 15 seconds without me pressing “q”
so what wlse could it be ?

Thanks ,

My test results:

API: /tool/bandwidth-test.=address=1.1.1.1.=duration=2s
Status: connecting, keeps trying and stops after 60 seconds (.section=64)

CLI: /tool bandwidth-test address=1.1.1.1 duration=2s
Status: connecting, keeps trying and stops after 60 seconds

API: /tool/bandwidth-test.=address=.=duration=2s
Status: connecting, keeps trying and stops after 60 seconds (.section=64)

CLI: /tool bandwidth-test address=“” duration=2s
Status: connecting, keeps trying and stops after 60 seconds

API: /tool/bandwidth-test.=address=172.16.1.1.=duration=2s
Status: can not connect, quits immediately

CLI: /tool bandwidth-test address=172.16.1.1 duration=2s
Status: can not connect, quits immediately

I get consistent behavior between CLI and API. Non-routable addresses fail directly and routable addresses remain in status “connecting” for 60s regardless of duration setting (note that address=“” is internally replaced by address=“::1”). I see no problems here.

Could you verify the SpeedAdress variable and compare it with the value used in CLI?

I have run the test to another device and now it’s OK
starnge…


I have another question
I want to show the time elapsed from the start of the test
so let say I give tesst of 20 seconds , some counter will show me 1,2,3…20

the counter is working , but in he window I only get the final resault and not all the steps
is there any way to show it? so when someone will press it he won’t think it get stuck…

also it will be very nice if I can show every seconds the rx-rate and not jsut in the resault in the end

Thanks ,

To get intermediate results, apply yield return in Read() function and change signature from List to IEnumerable as outlined in other thread :slight_smile:

I have change it ,
still get only the final response .
can you see where I did wrong?

this is the code :

  //Speed-Test button
        private void button5_Click(object sender, EventArgs e)
        {
            int counter = 0;

            mikrotik.Send("/tool/bandwidth-test");
            mikrotik.Send("=user=" + SpeedUSer);
            mikrotik.Send("=password=" + SpeedPass);
            mikrotik.Send("=address=" + SpeedAddress);
            mikrotik.Send("=duration=" + SpeedDuration , true);

           foreach (string h in mikrotik.Read())
            {
                if (h == "!done")
                {
                    break;
                }
               
                string[] Answer = h.Split('='); 
                int sizeAnswer = Answer.Length;
                for (int x = 0; x < sizeAnswer; x++)

                    switch (Answer[x])
                    {
                        case "!re":
                            break;

                        case "!done":
                            break;

                        case "status":
                            STstatus = Answer[x + 1];
                            break;

                        case "rx-current":
                            STRxCt = Answer[x + 1];
                            break;

                        case "rx-total-average":
                            STRxT = Answer[x + 1];
                            break;

                           default:
                            break;
                    }

                counter++;

                if ((counter==6) &&(STstatus == "connecting"))
                {
                    STRxCt = "Unable to Connect!";
                    STRxT = "Unable to Connect!";
                }


                int temp = (Convert.ToInt32(STRxT) / 1048576);
                STRxT = Convert.ToString(temp);

                int temp1 = (Convert.ToInt32(STRxCt) / 1048576);
                STRxCt = Convert.ToString(temp1);

                textBox19.Text = (STstatus);
                textBox20.Text = (STRxCt );
                textBox21.Text = (STRxT);
                textBox24.Text = (Convert.ToString(counter-1));
            }
    
        }

Thanks ,

Have you altered the Read() function in the MT class?

Yes
I did everything like I was told before

class MK
    {
        Stream connection;
        TcpClient con;

        public MK(string ip)
        {
            con = new TcpClient();
            con.Connect(ip, 8728);
            connection = (Stream)con.GetStream();
        }
        public void Close()
        {
            connection.Close();
            con.Close();
        }
        public bool Login(string username, string password)
        {
            Send("/login", true);
            string hash = Read().First().Split(new string[] { "ret=" }, StringSplitOptions.None)[1];
            Send("/login");
            Send("=name=" + username);
            Send("=response=00" + EncodePassword(password, hash), true);
            if (Read().First() == "!done")
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public void Send(string co)
        {
            byte[] bajty = Encoding.ASCII.GetBytes(co.ToCharArray());
            byte[] velikost = EncodeLength(bajty.Length);

            connection.Write(velikost, 0, velikost.Length);
            connection.Write(bajty, 0, bajty.Length);
        }
        public void Send(string co, bool endsentence)
        {
            byte[] bajty = Encoding.ASCII.GetBytes(co.ToCharArray());
            byte[] velikost = EncodeLength(bajty.Length);
            connection.Write(velikost, 0, velikost.Length);
            connection.Write(bajty, 0, bajty.Length);
            connection.WriteByte(0);
        }
        public IEnumerable<string> Read()
        {
            string o = "";
            byte[] tmp = new byte[4];
            long count;
            while (true)
            {
                tmp[3] = (byte)connection.ReadByte();
                //if(tmp[3] == 220) tmp[3] = (byte)connection.ReadByte(); it sometimes happend to me that 
                //mikrotik send 220 as some kind of "bonus" between words, this fixed things, not sure about it though
                if (tmp[3] == 0)
                {
                    yield return o;
                    if (o.Substring(0, 5) == "!done")
                    {
                        break;
                    }
                    else
                    {
                        o = "";
                        continue;
                    }
                }
                else
                {
                    if (tmp[3] < 0x80)
                    {
                        count = tmp[3];
                    }
                    else
                    {
                        if (tmp[3] < 0xC0)
                        {
                            int tmpi = BitConverter.ToInt32(new byte[] { (byte)connection.ReadByte(), tmp[3], 0, 0 }, 0);
                            count = tmpi ^ 0x8000;
                        }
                        else
                        {
                            if (tmp[3] < 0xE0)
                            {
                                tmp[2] = (byte)connection.ReadByte();
                                int tmpi = BitConverter.ToInt32(new byte[] { (byte)connection.ReadByte(), tmp[2], tmp[3], 0 }, 0);
                                count = tmpi ^ 0xC00000;
                            }
                            else
                            {
                                if (tmp[3] < 0xF0)
                                {
                                    tmp[2] = (byte)connection.ReadByte();
                                    tmp[1] = (byte)connection.ReadByte();
                                    int tmpi = BitConverter.ToInt32(new byte[] { (byte)connection.ReadByte(), tmp[1], tmp[2], tmp[3] }, 0);
                                    count = tmpi ^ 0xE0000000;
                                }
                                else
                                {
                                    if (tmp[3] == 0xF0)
                                    {
                                        tmp[3] = (byte)connection.ReadByte();
                                        tmp[2] = (byte)connection.ReadByte();
                                        tmp[1] = (byte)connection.ReadByte();
                                        tmp[0] = (byte)connection.ReadByte();
                                        count = BitConverter.ToInt32(tmp, 0);
                                    }
                                    else
                                    {
                                        //Error in packet reception, unknown length
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                for (int i = 0; i < count; i++)
                {
                    o += (Char)connection.ReadByte();
                }
            }
        }
        byte[] EncodeLength(int delka)
        {
            if (delka < 0x80)
            {
                byte[] tmp = BitConverter.GetBytes(delka);
                return new byte[1] { tmp[0] };
            }
            if (delka < 0x4000)
            {
                byte[] tmp = BitConverter.GetBytes(delka | 0x8000);
                return new byte[2] { tmp[1], tmp[0] };
            }
            if (delka < 0x200000)
            {
                byte[] tmp = BitConverter.GetBytes(delka | 0xC00000);
                return new byte[3] { tmp[2], tmp[1], tmp[0] };
            }
            if (delka < 0x10000000)
            {
                byte[] tmp = BitConverter.GetBytes(delka | 0xE0000000);
                return new byte[4] { tmp[3], tmp[2], tmp[1], tmp[0] };
            }
            else
            {
                byte[] tmp = BitConverter.GetBytes(delka);
                return new byte[5] { 0xF0, tmp[3], tmp[2], tmp[1], tmp[0] };
            }
        }

        public string EncodePassword(string Password, string hash)
        {
            byte[] hash_byte = new byte[hash.Length / 2];
            for (int i = 0; i <= hash.Length - 2; i += 2)
            {
                hash_byte[i / 2] = Byte.Parse(hash.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
            }
            byte[] heslo = new byte[1 + Password.Length + hash_byte.Length];
            heslo[0] = 0;
            Encoding.ASCII.GetBytes(Password.ToCharArray()).CopyTo(heslo, 1);
            hash_byte.CopyTo(heslo, 1 + Password.Length);

            Byte[] hotovo;
            System.Security.Cryptography.MD5 md5;

            md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();

            hotovo = md5.ComputeHash(heslo);

            //Convert encoded bytes back to a 'readable' string
            string navrat = "";
            foreach (byte h in hotovo)
            {
                navrat += h.ToString("x2");
            }
            return navrat;
        }
    


}

Try this after setting control values:

System.Windows.Forms.Application.DoEvents();

This allows the screen to update.

Source:
http://share.linqpad.net/334xk5.linq

Screen shot:
2017-06-28_13-25-20.png

yes !
now it’s working
Thank you vety much!

so jsut to be clear , and to say it in simple words -
this command “refresh” the page while a function is running?


Thanks ,

Among other things.

https://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents(v=vs.110).aspx