2

I'm trying to write a voting server and client, so you start the program and it displays the voting form and you can vote on various items. For the server part I've got the server running in a separate thread, but it's using a lot of CPU, how do I reduce the amount of CPU it's using?

this is my server:

        Form1 main = new Form1();

        try
        {
            IPAddress ipAd = IPAddress.Parse(main.ipAddress); //use local m/c IP address, and use the same in the client

            /* Initializes the Listener */
            TcpListener myList = new TcpListener(ipAd, 55548);

            /* Start Listeneting at the specified port */
            myList.Start();

            while (true)
            {
                string message = "";
                Socket s = myList.AcceptSocket();



                if (main.users.Contains(s.RemoteEndPoint.ToString()) == false)
                    main.users.Add(s.RemoteEndPoint.ToString());



                byte[] b = new byte[500];
                int k = s.Receive(b);



                for (int i = 0; i < k; i++)
                {
                    message += (Convert.ToString(b[i]));
                }

                string[] messageArray = message.Split('/');

                MessageBox.Show("help");

                if (messageArray[0].CompareTo("vote") == 0)
                {

                    if (main.votes.ContainsKey(messageArray[1]) != true) main.votes.Add(messageArray[1], 1);
                    else main.votes[messageArray[1]]++;

                    string[] temp = main.textBox1.Text.Split(' ');
                    int numVotes = Convert.ToInt32(temp[1]);
                    numVotes++;
                    main.textBox1.Text = temp[0] + " " + Convert.ToString(numVotes);

                }
                if (messageArray[0].CompareTo("start") == 0)
                {
                    main.updateEverything();
                }
                if(messageArray[0].CompareTo("withdraw") == 0)
                {
                    main.votes[messageArray[1]]--;

                    string[] temp = main.textBox1.Text.Split(' ');
                    int numVotes = Convert.ToInt32(temp[1]);
                    numVotes--;
                    main.textBox1.Text = temp[0] + " " + Convert.ToString(numVotes);
                }

                /* clean up */
                s.Close();
                myList.Stop();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine("Error..... " + e.StackTrace);
        }
Steve
  • 213,761
  • 22
  • 232
  • 286
user1911422
  • 43
  • 1
  • 7
  • 1
    `while (true)` usually raises flags: is it a 'tight loop' (aka busy loop)? – sehe Dec 18 '12 at 00:12
  • Finding code that burns 100% core is pretty easy, even without a profiler. Just use Debug + Break All a couple of times and you have very high odds that the debugger consistently breaks in the hot code. – Hans Passant Dec 18 '12 at 01:04
  • (a) you are assuming that bytes==chars. This only holds true for a subset of character sets. (b) it is not safe to assume that all of the message has been read in a single `Receive`. It is entirely possible that a single call to receive may yield less bytes than you expect, requiring more receives to read the rest of the message. Sending strings without an indication of length essentially means that it is impossible to know when you have received the entire message, unless your protocol means the client closes the connection immediately. In this case, `Receive` until it returns 0 bytes. – spender Dec 18 '12 at 01:13
  • Assuming that `myList` is a listener of some sort. Why are you stopping it inside your main loop? – spender Dec 18 '12 at 01:17
  • ..you also don't appear to ever break out of that while loop.. – Simon Whitehead Dec 18 '12 at 01:38

2 Answers2

1

You are using a blocking type of connection. The loop you create causes a CPU overhead because of the TcpListener.AcceptConnection(). Your solution is to accept non-blocking socket connections, which is done by receiving data from socket asynchronously.

Here's the msdn link that explains how it works. http://msdn.microsoft.com/en-us/library/dxkwh6zw.aspx

detay
  • 1,082
  • 11
  • 19
0

I see you have string concatenations which basically affects performance; try using a StringBuilder - the message variable should be of type StringBuilder.

csg
  • 2,047
  • 2
  • 22
  • 35