100分求 socket服务器端占用CPU100% 高手帮忙~~~~!

时间:2021-04-23 18:02:33
用C#写了个WINDOWS服务,做SOCKET的服务器端
不过在运行一段时间后发现CPU利用率总会升到100%
造成服务器运行缓慢,代码如下
TcpListener tcl = new TcpListener(IPAddress.Parse(fconfig.Server),listenport);
tcl.Start();
while(true)
{
                        Thread.Sleep(200);
clientsocket = tcl.AcceptSocket();         
clientservice = new Thread(new ParameterizedThreadStart(ServerChart));
clientservice.Start(clientsocket.RemoteEndPoint.ToString());
}
在网上查到说是线程一直在运行(while循环),后来加上了 Thread.Sleep(200);效果也不是很明显

以前没有做过SOCKET的开发,这个服务端是不能停的。

哪位高手能提供更好的方案或解决方法。

34 个解决方案

#1



while(true)
{
                        Thread.Sleep(200);
clientsocket = tcl.AcceptSocket();       
clientservice = new Thread(new ParameterizedThreadStart(ServerChart));
clientservice.Start(clientsocket.RemoteEndPoint.ToString());


你在while里无限的创建新线程啊?!
每次循环都创建一个新线程,CPU肯定100%!

  if(...)
{
clientservice = new Thread(new ParameterizedThreadStart(ServerChart));
clientservice.Start(clientsocket.RemoteEndPoint.ToString());
}


#2


while(true) 

                        Thread.Sleep(200); 
clientsocket = tcl.AcceptSocket();        
clientservice = new Thread(new ParameterizedThreadStart(ServerChart)); 
clientservice.Start(clientsocket.RemoteEndPoint.ToString()); 


没命的开线程啊..... 

考虑使用异步方式把
http://blog.csdn.net/zgke/archive/2009/01/20/3838844.aspx

#3


嗯,创建的线程太多了

#4


while..
千万别这么做
不拖死CPU才怪
用Backgroundworker可用加异步委托方式来做

#5


用异步吧.完成端口对你现在可能难了点

#6


jf

#7


to zhouyanfss:客户端和服务器端通讯,不是要一个客户端连接建一个线程吗?在客户端关闭时线程会关闭的

to zgke:谢谢,我参考下,向你看齐

#8



while(true) 

  if(tcl.Pending)
  {
     clientsocket = tcl.AcceptSocket();        
     clientservice = new Thread(new ParameterizedThreadStart(ServerChart)); 
     clientservice.Start(clientsocket.RemoteEndPoint.ToString()); 
   }
     else
                        Thread.Sleep(200); 

#9



while(true) 

  if(tcl.Pending())
  {
     clientsocket = tcl.AcceptSocket();        
     clientservice = new Thread(new ParameterizedThreadStart(ServerChart)); 
     clientservice.Start(clientsocket.RemoteEndPoint.ToString()); 
   }
     else
                        Thread.Sleep(200); 


#10


tcplisten应该是自己会创建线程的,你只要写收发事件就可以了

#11


也可以在前边加一个flg进行判断
保证线程只开一次或者调用前把上个线程给杀死

#12


直接使用线程池就好了,有的时候会发现同时请求用户过多,如果不用线程池,系统会over的,除非你手动控制线程数量。

如果是长连接,建议使用异步回调
如果是短连接,使用同步稍微好点,但无论如何,个人建议使用线程池来进行操作。

#13


學習學習

#14


该回复于2014-07-30 14:22:02被版主删除

#15


友情帮顶

#16


死循环了  休眠一下  或者限定数量

#17


学习~

#18


不要沉,顶起来。。

[align=center]****************************************************************
            看帖一定要回的,分也一定要接的。^_^
****************************************************************[/align]

#19


因为你在不断建立线程,一个服务器的线程数是有限的

#20


谢谢各位,我是初做SOCKET通讯.
好多都不了解.各位有写过这方面知识的可以把连接贴出来
大家一起学习

#21


参考下面代码,监听应该只开启一个,然后使用循环创建TCP连接,AcceptTcpClient方法将阻塞当前线程,直到有新的连接进来,这样就不会消耗系统资源了。
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

class MyTcpListener
{
  public static void Main()
  { 
    TcpListener server=null;   
    try
    {
      Int32 port = 13000;
      IPAddress localAddr = IPAddress.Parse("127.0.0.1");

      server = new TcpListener(localAddr, port);

      server.Start();

      Byte[] bytes = new Byte[256];
      String data = null;

      while(true) 
      {
        Console.Write("Waiting for a connection... ");

        TcpClient client = server.AcceptTcpClient();            
        Console.WriteLine("Connected!");

        data = null;

        NetworkStream stream = client.GetStream();

        int i;

        while((i = stream.Read(bytes, 0, bytes.Length))!=0) 
        {   
          data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
          Console.WriteLine("Received: {0}", data);

          data = data.ToUpper();

          byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);

          stream.Write(msg, 0, msg.Length);
          Console.WriteLine("Sent: {0}", data);            
        }
        client.Close();
      }
    }
    catch(SocketException e)
    {
      Console.WriteLine("SocketException: {0}", e);
    }
    finally
    {
       server.Stop();
    }
    Console.WriteLine("\nHit enter to continue...");
    Console.Read();
  }   
}

#22


学习~

#23


去掉while(true) 

#24


如果需要使用多线程,应该在数据接收和发送的时候多线程处理,创建TCP连接的时候不能那样,必须一个个排队创建,不然就是无底洞,你又不知道可能创建多少个连接,不停地开线程来等待外来链接会导致系统资源耗尽。

#25


好贴子,学习了,要是能发点异步的代码参考下就更好了~

#26


线程太多

#27


绑定

#28


TcpClient client = server.AcceptTcpClient
改为
server.BeginAcceptSocket

这样只有连接接入的时候才执行之下的代码。

#29


线程问题

#30


 不懂,只能帮顶啦!

#31



  TcpListener tcl = new TcpListener(IPAddress.Parse(fconfig.Server),listenport); 
  tcl.Start(); 
  Thread thread=new Thread(ThreadMehtod);
  thread.start();
}

public void ThreadMehtod()
{
  while(true) 
  { 
      clientsocket = tcl.AcceptSocket();        
      clientservice = new Thread(new ParameterizedThreadStart(ServerChart)); 
      clientservice.Start(clientsocket.RemoteEndPoint.ToString()); 
   } 
}

#32


当然对于socket网络通信的和IO的操作最好使用异步方式

#33


你确定是整个地方引起的??

#34


have a look

#1



while(true)
{
                        Thread.Sleep(200);
clientsocket = tcl.AcceptSocket();       
clientservice = new Thread(new ParameterizedThreadStart(ServerChart));
clientservice.Start(clientsocket.RemoteEndPoint.ToString());


你在while里无限的创建新线程啊?!
每次循环都创建一个新线程,CPU肯定100%!

  if(...)
{
clientservice = new Thread(new ParameterizedThreadStart(ServerChart));
clientservice.Start(clientsocket.RemoteEndPoint.ToString());
}


#2


while(true) 

                        Thread.Sleep(200); 
clientsocket = tcl.AcceptSocket();        
clientservice = new Thread(new ParameterizedThreadStart(ServerChart)); 
clientservice.Start(clientsocket.RemoteEndPoint.ToString()); 


没命的开线程啊..... 

考虑使用异步方式把
http://blog.csdn.net/zgke/archive/2009/01/20/3838844.aspx

#3


嗯,创建的线程太多了

#4


while..
千万别这么做
不拖死CPU才怪
用Backgroundworker可用加异步委托方式来做

#5


用异步吧.完成端口对你现在可能难了点

#6


jf

#7


to zhouyanfss:客户端和服务器端通讯,不是要一个客户端连接建一个线程吗?在客户端关闭时线程会关闭的

to zgke:谢谢,我参考下,向你看齐

#8



while(true) 

  if(tcl.Pending)
  {
     clientsocket = tcl.AcceptSocket();        
     clientservice = new Thread(new ParameterizedThreadStart(ServerChart)); 
     clientservice.Start(clientsocket.RemoteEndPoint.ToString()); 
   }
     else
                        Thread.Sleep(200); 

#9



while(true) 

  if(tcl.Pending())
  {
     clientsocket = tcl.AcceptSocket();        
     clientservice = new Thread(new ParameterizedThreadStart(ServerChart)); 
     clientservice.Start(clientsocket.RemoteEndPoint.ToString()); 
   }
     else
                        Thread.Sleep(200); 


#10


tcplisten应该是自己会创建线程的,你只要写收发事件就可以了

#11


也可以在前边加一个flg进行判断
保证线程只开一次或者调用前把上个线程给杀死

#12


直接使用线程池就好了,有的时候会发现同时请求用户过多,如果不用线程池,系统会over的,除非你手动控制线程数量。

如果是长连接,建议使用异步回调
如果是短连接,使用同步稍微好点,但无论如何,个人建议使用线程池来进行操作。

#13


學習學習

#14


该回复于2014-07-30 14:22:02被版主删除

#15


友情帮顶

#16


死循环了  休眠一下  或者限定数量

#17


学习~

#18


不要沉,顶起来。。

[align=center]****************************************************************
            看帖一定要回的,分也一定要接的。^_^
****************************************************************[/align]

#19


因为你在不断建立线程,一个服务器的线程数是有限的

#20


谢谢各位,我是初做SOCKET通讯.
好多都不了解.各位有写过这方面知识的可以把连接贴出来
大家一起学习

#21


参考下面代码,监听应该只开启一个,然后使用循环创建TCP连接,AcceptTcpClient方法将阻塞当前线程,直到有新的连接进来,这样就不会消耗系统资源了。
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;

class MyTcpListener
{
  public static void Main()
  { 
    TcpListener server=null;   
    try
    {
      Int32 port = 13000;
      IPAddress localAddr = IPAddress.Parse("127.0.0.1");

      server = new TcpListener(localAddr, port);

      server.Start();

      Byte[] bytes = new Byte[256];
      String data = null;

      while(true) 
      {
        Console.Write("Waiting for a connection... ");

        TcpClient client = server.AcceptTcpClient();            
        Console.WriteLine("Connected!");

        data = null;

        NetworkStream stream = client.GetStream();

        int i;

        while((i = stream.Read(bytes, 0, bytes.Length))!=0) 
        {   
          data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
          Console.WriteLine("Received: {0}", data);

          data = data.ToUpper();

          byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);

          stream.Write(msg, 0, msg.Length);
          Console.WriteLine("Sent: {0}", data);            
        }
        client.Close();
      }
    }
    catch(SocketException e)
    {
      Console.WriteLine("SocketException: {0}", e);
    }
    finally
    {
       server.Stop();
    }
    Console.WriteLine("\nHit enter to continue...");
    Console.Read();
  }   
}

#22


学习~

#23


去掉while(true) 

#24


如果需要使用多线程,应该在数据接收和发送的时候多线程处理,创建TCP连接的时候不能那样,必须一个个排队创建,不然就是无底洞,你又不知道可能创建多少个连接,不停地开线程来等待外来链接会导致系统资源耗尽。

#25


好贴子,学习了,要是能发点异步的代码参考下就更好了~

#26


线程太多

#27


绑定

#28


TcpClient client = server.AcceptTcpClient
改为
server.BeginAcceptSocket

这样只有连接接入的时候才执行之下的代码。

#29


线程问题

#30


 不懂,只能帮顶啦!

#31



  TcpListener tcl = new TcpListener(IPAddress.Parse(fconfig.Server),listenport); 
  tcl.Start(); 
  Thread thread=new Thread(ThreadMehtod);
  thread.start();
}

public void ThreadMehtod()
{
  while(true) 
  { 
      clientsocket = tcl.AcceptSocket();        
      clientservice = new Thread(new ParameterizedThreadStart(ServerChart)); 
      clientservice.Start(clientsocket.RemoteEndPoint.ToString()); 
   } 
}

#32


当然对于socket网络通信的和IO的操作最好使用异步方式

#33


你确定是整个地方引起的??

#34


have a look