简体   繁体   中英

Multi-threaded TCP Server with high CPU and keep increase thread count

I wrote simple Multi-Threaded TCP C# Server program.After I run my program I got high CPU usage and thread count is keep increasing in task manager. Can anyone help me to figure out how to solve and give suggestions?

This is my code.

public class Program
{
    static void Main(string[] args)
    {
        int _Port = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["TCPPort"]);
        string _IP = System.Configuration.ConfigurationManager.AppSettings["TCPIP"];
        TcpServer server = new TcpServer(_Port);
    }
}

public class TcpServer
{
    private TcpListener _server;
    private Boolean _isRunning;
    private static int defaultMax = 8;
    public TcpServer(int port)
    {
        _server = new TcpListener(IPAddress.Any, port);
        _server.Start();
        _isRunning = true;          
        LoopClients();
    }

    public void LoopClients()
    {
        while (_isRunning)
        {

            TcpClient newClient = _server.AcceptTcpClient();
            SentFirstTimeData_New(newClient);
            Thread t = new Thread(new ParameterizedThreadStart(HandleClient));
            t.Start(newClient);
        }
    }

    public void HandleClient(object obj)
    {
        int requestCount = 0;
        byte[] bytesFrom = new byte[209666];
        string dataFromClient = null;
        Byte[] sendBytes = null;
        requestCount = 0;
        int byteread = 0;
        string respdata = string.Empty;
        byte[] buffer = new byte[4096];
        int numberOfBytesRead;

        TcpClient client = (TcpClient)obj;         
        NetworkStream networkStream = client.GetStream();
        IPAddress address = ((IPEndPoint)client.Client.RemoteEndPoint).Address;

        Boolean bClientConnected = true;
        int id = Thread.CurrentThread.ManagedThreadId;
        while (bClientConnected)
        {
            try {
                if (networkStream.DataAvailable)
                {
                    byteread = networkStream.Read(bytesFrom, 0, (int)client.ReceiveBufferSize);
                    dataFromClient = Encoding.ASCII.GetString(bytesFrom).TrimEnd('\0');
                    System.Text.Encoding.ASCII.GetString(bytesFrom);

                    XmlDocument doc = new XmlDocument();
                    string xml = Encoding.UTF8.GetString(bytesFrom).TrimEnd('\0');
                    doc.LoadXml(xml);
                    XElement incc = XElement.Load(new XmlNodeReader(doc));
                    respdata = AysncTCPIncomeString(incc);

                    sendBytes = Encoding.ASCII.GetBytes(respdata);
                    networkStream.Write(sendBytes, 0, sendBytes.Length);
                    networkStream.Flush();
                }
            }
            catch (Exception ex)
            {
                Helper.WriteLog("Exception=" + ex.Message);
            }
        }
    }

    public void SentFirstTimeData_New(TcpClient tc)
    {
        try
        {
            int threadid = Thread.CurrentThread.ManagedThreadId;
            string Msg = HLStatusResponse.FirstTimeStatusSuccessfulResponse("STATUS", "1");
            NetworkStream _NetworkStream = tc.GetStream();
            if (_NetworkStream != null)
            {
                byte[] data = Encoding.ASCII.GetBytes(Msg);
                _NetworkStream.Write(data, 0, data.Length);

                Helper.WriteLog("ThreadId=" + threadid.ToString() + ";SentFirstTimeData :\t " + Msg);
            }
        }
        catch (Exception ex)
        {
            Helper.WriteLog("Sent Though Tcp Eror :" + ex.ToString());
        }
    }
}

Consider this chunk of code:

    Boolean bClientConnected = true;
    int id = Thread.CurrentThread.ManagedThreadId;
    while (bClientConnected)
    {
        try {
            if (networkStream.DataAvailable)

You never change bClientConnected - it is always true, so your loop never exits.

Also, if the connection is idle - that is, if networkStream.DataAvailable is false - then you just spin in your while loop doing nothing.

If you have a thread per client, why don't you just let the thread be blocked by performing a read from the socket? Then the thread won't spin wasting cpu doing nothing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM