我用c#编写了一个Socket的C/S程序,客户端和服务器端都有界面,服务器端需要时时将接收到的信息显示到界面上。虽然我采用了多线程,但是由于主线程中需要一直监听客户端,我采用了死循环!
 while (true)
            {
                server.Listen(5);
                Thread myThread = new Thread(new ThreadStart(MyNewSocket));
                myThread.Start();
                myThread.IsBackground = true;
      
            }
这样一来导致服务器处于假死状态,请问有没有什么好的办法解决?在线等................

解决方案 »

  1.   

    while (true)
                {
                    server.Listen(5);
                    Thread myThread = new Thread(new ThreadStart(MyNewSocket));
                    myThread.Start();
                    myThread.IsBackground = true;               sleep(1000);  //加这句话,使得本线程放弃cpu时间片,可以使得其他线程有机会执行。就不会有假死的现象了
         
                } 
      

  2.   

    你这个while是在主线程上面的吗?如果是的话建议用一个线程来监听
      

  3.   


            public void Listen()
            {
                Thread t = new Thread(listenConnection);
                Console.WriteLine("Listening......");
                t.Start();
            }
    listenConnection作为一个私有方法,包装一下你的while语句块;
    这样就不会有太大问题了;
      

  4.   

    顺便说一下,写一个c/s的socket通讯并不难,难的是写一通讯模块给其它的程序用,并且满足各种各样的要求(协议类型,拆包,组包,收发消息等等)
      

  5.   

    LZ你在while里面new Thread,这样的话你到底new了多少Thread呢?不死才怪
      

  6.   

    你到底想开多少个线程来接收Socket啊,这样不卡死你,网络资源也要被你吃干净了。
    你把下面那个BeginAccept方法放到独立的线程中运行,就不会卡你的界面了,也不会吃死你的资源了。        public static ManualResetEvent allDone = new ManualResetEvent(false);
            public void BeginAccept(string IP, string Port)
            {
                //一段初始化方法
                  //................
                //................
                server.Listen(100);
                while (true)
                {
                    allDone.Reset();
                    IAsyncResult result = server.BeginAccept(new AsyncCallback(AcceptConn), server);
                    allDone.WaitOne();
                }
            }        public void AcceptConn(IAsyncResult iar)
            {
                allDone.Set();
                Socket s = (Socket)iar.AsyncState;
                //开始接收或发送
                 //...........
            }
      

  7.   


    没有While是另外开辟的一个线程!
      

  8.   


    我对线程理解的不太好,我的意思是,让server一直处于监听状态,每当有客户端请求时,就创建一个新线程来接受数据,如果没有客户端请求,那么就就阻塞在listen函数那了!
    我不知道理解的对不对,刚接触不知道如何实现,还请各位多多指教!
      

  9.   

    LZ你很少接触多线程吧?主线程都在不停的运行监听,你每隔5个MS就运行一次,界面当然没有时间来处理了。
    如果你想响应下按钮事件,可以加一个APPLICATION。DOEVENT。
    如果你想更流畅的运行主程序,就另外开一个THREAD来运行这个监听服务。
      

  10.   


    我上面拷贝出来的代码,没有在主线程中,是另外开辟的线程!
    现在我的疑问是:曾经在一本书上看到过,如果一个线程开着死循环空转,那么它很可能一直占用CPU,我怀疑是由于监听线程在不断地占用CPU使得,主线轮到CUP的时间太少。
    具体原因,我不清楚,刚接触多线程和在多线程中运用控件,所以不知道原因在哪
      

  11.   

    今天调试时,正如各位所说,确实在无限创建线程,本来以为Listen是一个阻塞函数,现在发现错了!
    如果要是加一个判断条件该如何判断呢。
    while("接受到新的请求")
    {
        创建新的线程。
    }
    怎么才知道有新的请求了呢。Listen的返回值是void。
      

  12.   

    Listen不会阻塞,只是将Socket置为侦听状态,应该在这之后使用Accept,然后会阻塞,有客户发起连接时就会返回一个Socket。
      

  13.   

    while (true) 
                { 
                    server.Listen(5); 
                    Thread myThread = new Thread(new ThreadStart(MyNewSocket)); 
                    myThread.Start(); 
                    myThread.IsBackground = true; 
          
                } 无限的创建线程.. 你的while应该在 MyNewSocket方法里while()可以考虑使用 Application.DoEvents(); 让系统处理其他的消息.
      

  14.   

    while (true) 
                { 
                    server.Listen(5); 
                    Thread myThread = new Thread(new ThreadStart(MyNewSocket)); 
                    myThread.Start(); 
                    myThread.IsBackground = true; 
          
                } 
    刚没有看仔细,问题出在你的监听方式上。不是你这个样子的。
    //你用这个来监听
    server.Listen(5);
    但不一定就会有连接过来要发送数据,
    所以你下面的执行 Thread myThread = new Thread(new ThreadStart(MyNewSocket)); 
    这里是不对的。
    楼上有一个异步的参考,我给你一个同步的:
    while (isListener)
                    {
                        System.Threading.Thread.Sleep(100);
                        isRun = true;
                        //有连接请求
                        if (localServer.Pending())
                        {
                            Socket currentSocket = localServer.AcceptSocket();
                            IPEndPoint currPoint = (IPEndPoint)currentSocket.RemoteEndPoint;
                            CServer485 current485 = new CServer485(currPoint.Address.ToString(), currPoint.Port, currentSocket);
                            CDealBuseness currDeal = new CDealBuseness(ref current485, currentForm, delegtCard, delegt485);
                            currDeal.Start();
                                               }
                    }
      

  15.   


    那该如何,另外开辟一个线程来处理新接收的Socket呢
    我现在想了两种
    1. 创建固定数目的线程 类似线程池
    2. 创建一个全局Socket来接受新的请求,然后传递到新的线程内,但是感觉这种不安全。
      

  16.   

    对于Accept到的Socket如何处理,可以按你自己的习惯来,你说的两种方法我觉得都可以,没有什么不安全。
      

  17.   

    假死的原因是因为 server.Listen(5)一直在监听 等待数据
    解决方式:将监听循环封装到方法里 用线程调用此方法