2012-09-03 3 views
-1

TCP 클라이언트를 더 많이 받아들이고 연결된 모든 클라이언트로부터 지속적인 메시지를받는 tcp 서버 응용 프로그램이 있습니다.TCP 서버 응용 프로그램을 실행하는 동안 100 % CPU 사용량

public void KeepListening() 
    { 
     while (IsRunning) 
     { 
       try 
       { 
         Thread.Sleep(20); 
         if (tcpListener.Pending()) 
         { 
          //Get the socket obtained from the tcpListener 
          TcpClient _Client = tcpListener.AcceptTcpClient(); 
          NetworkStream ns = _Client.GetStream(); 
          Thread.Sleep(20); 
          if (Stop_Status == false) 
          { 
           if (_Client.Connected) 
           { 
            int DataBytes = _Client.Available; 
            byte[] data = new byte[DataBytes]; 
            if (ns.DataAvailable == true) 
            { 
             ns.Read(data, 0, DataBytes); 
             string Key = ASCIIEncoding.ASCII.GetString(data); 
             string[] KeyCodes = Key.Split(','); 
             if (Key != "" && ((KeyCodes[0].StartsWith("i")))) 
              ProcessClient(_Client, KeyCodes[0], Key); 
            } 
           } 
          } 
          else 
          { 
           ns.Flush(); 
          } 
         } 
       } 
       catch 
       { 

       } 
     } 
    } 


    void ProcessClient(TcpClient _Client, string Key,string Msg) 
    { 
     try 
     { 
      if (hashTable_Users.Count > 0) 
      { 
       if (hashTable_Users.Contains(Key)) 
       { 
        hashTable_Users.Remove(Key); 
       } 
      } 
      hashTable_Users.Add(Key, _Client); 
      hashusers = hashTable_Users.Count; 
      this.MessageFromClient(Key, serverPortNo.ToString(), Msg); 

      //StreamWriter sw = new StreamWriter(_Client.GetStream()); 
      //sw.WriteLine("1"); 
      //sw.Flush(); 

      object[] objarr = new object[5]; 
      objarr[0] = _Client; 
      objarr[1] = Key; 
      Thread ReceiveFromClient = new Thread(new ParameterizedThreadStart(ReceiveFromClients)); 
      ReceiveFromClient.Start(objarr); 
     } 
     catch 
     { 

     } 
    } 
    public void ReceiveFromClients(object obj) 
    { 
      object[] objarr = (object[])obj; 
      TcpClient _Client = (TcpClient)objarr[0]; 
      NetworkStream ns = _Client.GetStream(); 
      while (IsRunning) 
      { 
       if (Stop_Status == false) 
       { 
        if (_Client.Connected) 
        { 
         if (ns.DataAvailable) 
         { 
          try 
          { 
           int numBytesRead = _Client.Available; 
           byte[] data = new byte[numBytesRead]; 
           ns.Read(data, 0, numBytesRead); 
           string MsgReceived = ASCIIEncoding.ASCII.GetString(data); 
           string clientKey = objarr[1].ToString(); 
           this.MessageFromClient(clientKey, serverPortNo.ToString(), MsgReceived); 
          } 
          catch 
          { 

          } 
         } 
        } 
        else 
        { 
         break; 
        } 
       } 
       else 
       { 
        ns.Flush(); 
       } 
      } 
    } 

KeepListening()은 요청을 보내는 클라이언트를 받아들이는 데 사용됩니다. ProcessClient()ReceiveFromClients()은 클라이언트에서 메시지를 수신하는 데 사용됩니다.

이 응용 프로그램은 100 % cpu를 사용합니다.

CPU 사용을 줄이기 위해해야 ​​할 일을 제안하십시오.

+1

CPU 사용량을 줄이려면 프로파일 러를 사용하여 대부분의 CPU 리소스를 소비하는 코드 및 코드 줄을 찾습니다. 그런 다음 응용 프로그램을 재고하고 너무 많은 리소스를 사용하는 코드를 다시 작성하십시오. –

+0

놀라지 않습니다. 작업주기 사이에 수면 스레드는 20ms 밖에 걸리지 않습니다. 나는 영원히 작동한다. –

+1

적절한 비동기 TCP 서버를 작성하고 폴링하지 않아야합니다. BeginReceive 및 BeginAccept를 사용하십시오. – BlueM

답변

1

, ReceiveFromClients가 소모됩니다 대부분의 CPU는 while (IsRunning)과 데이터 만 사용할 수있는 경우 읽기 때문에 발생합니다.

이 문제를 해결하려면 IsAvailabele을 확인하지 말고 ReadTimeOut이 발생하거나 일부 데이터가 읽힐 때까지 스레드를 차단하는 ReadMethod를 호출하십시오. 받은 바이트 수에 따라 데이터를 처리하십시오.

+0

감사합니다. 나를 위해 일했다. – GSReddy

+0

실험적이지 않은 경우 코드를 다시 작성하십시오. 절전 모드는 서버/클라이언트 코드에 없습니다. 비동기 소켓 프로그래밍을 활용하십시오. – BlueM

+0

안녕하세요 Sudhakar, TCP 서버의 단일 인스턴스를 실행하면 CPU 사용률이 50-70 % 사이입니다. 하지만 두 개의 서버 인스턴스 (동일한 IP, Diff 포트)를 실행 중이면 다시 CPU가 100 %의 메모리를 소비합니다. 무엇을해야합니까? – GSReddy

0

CPU 사용량을 줄이기 위해해야 ​​할 일을 제안하십시오.

음이 나쁜 시작과 같습니다 당신이 반복적으로 예외를 받고있는 경우, 당신이 그것에 대해 결코 알지 못할 것이다

while (IsRunning) 
{ 
    try 
    { 
     ... 
    } 
    catch 
    { 
    } 
} 

- 그냥 루핑 유지한다. 또 다른 빈 catch 블록이 있습니다 ... 당신 정말로은 모든 것을 잡아서 그냥 로깅하지 않고 계속 진행해서는 안됩니다. 마찬가지로 여기

: IsRunning 사실이며, Stop_Status가 그냥 반복 Flush 호출 꽉 루프 것, 거짓

while (IsRunning) 
{ 
    if (Stop_Status == false) 
    { 
     ... 
    } 
    else 
    { 
     ns.Flush(); 
    } 
} 

경우 ... 코드에보고함으로써

관련 문제