本帖最后由 jiangting1986 于 2014-01-16 21:08:54 编辑

解决方案 »

  1.   

     Action<TcpClient> ac = (c) => ReadThread(c);<<==你这句是连接了一个客户端就开一个线程吧。
      

  2.   


    是我的错,ReadThread()是一个方法,我没有贴出来,是对数据进行处理的方法,部分代码如下
      /// <summary>
            /// 读数据
            /// </summary>
            /// <param name="ar"></param>
            private void ReadThread(TcpClient client)
            {
                //string name = Guid.NewGuid().ToString();
                Debug.WriteLine("一次连接:");// + name);
                var ns = client.GetStream();
                
                int times = 350;
                // ReadWriteObject readWo = new ReadWriteObject(client);
                string machineId = "";
                
                byte[] buff = new byte[1024 * 8];
      

  3.   

       Action<TcpClient> ac = (c) => ReadThread(c);
                    ac.BeginInvoke(client, null, null);
    这种是异步的,是线程的
      

  4.   

    已经跟客户机连好管道了
    var ns_f = client.GetStream();
    何必再
    Action<TcpClient> ac = (c) => ReadThread(c);
    ac.BeginInvoke(client, null, null); 
    var ns = client.GetStream(); 
    不如改这样看一下,是不是不要这么多线程了呢?
    //Action<TcpClient> ac = (c) => ReadThread(c);
    //ac.BeginInvoke(client, null, null); 
    ReadThread(ns_f);
    void ReadThread(NetworkStream networkStream)
      

  5.   


    那这个线程是什么时候释放的?我的线程一直在增加执行完就自动释放,你里面是不是写死循环了,贴出来代码不全里面是没有死循环的,因为程序可以执行几天,如果是死循环的话会很快就崩溃才对啊。。下面的那个代码就是这样子了,单纯的处理数据而已 /// <summary>
            /// 读数据
            /// </summary>
            /// <param name="ar"></param>
            private void ReadThread(TcpClient client)
            {
                Debug.WriteLine("一次连接:");// + name);
                var ns = client.GetStream();
                
                int times = 350;
                string machineId = "";
                
                byte[] buff = new byte[1024 * 8];            try
                {
                    while (IsConnected(client) && !isStop)
                    {
                       
                        if (client.Available == 0)
                        {
                           
                            Thread.Sleep(200);
                            
                            continue;
                        }                    var count = ns.Read(buff, 0, buff.Length);
                        string str = System.Text.Encoding.Default.GetString(buff, 0, count).Replace("\r\n", "").ToUpper();
      

  6.   


    那这个线程是什么时候释放的?我的线程一直在增加执行完就自动释放,你里面是不是写死循环了,贴出来代码不全里面是没有死循环的,因为程序可以执行几天,如果是死循环的话会很快就崩溃才对啊。。下面的那个代码就是这样子了,单纯的处理数据而已 /// <summary>
            /// 读数据
            /// </summary>
            /// <param name="ar"></param>
            private void ReadThread(TcpClient client)
            {
                Debug.WriteLine("一次连接:");// + name);
                var ns = client.GetStream();
                
                int times = 350;
                string machineId = "";
                
                byte[] buff = new byte[1024 * 8];            try
                {
                    while (IsConnected(client) && !isStop)
                    {
                       
                        if (client.Available == 0)
                        {
                           
                            Thread.Sleep(200);
                            
                            continue;
                        }                    var count = ns.Read(buff, 0, buff.Length);
                        string str = System.Text.Encoding.Default.GetString(buff, 0, count).Replace("\r\n", "").ToUpper();        while (IsConnected(client) && !isStop) 
          估计是这个造成了死循环,
           把 IsConnected 函数发出来,可嫩连接已经断开了,不能判断出来
      

  7.   


    那这个线程是什么时候释放的?我的线程一直在增加执行完就自动释放,你里面是不是写死循环了,贴出来代码不全里面是没有死循环的,因为程序可以执行几天,如果是死循环的话会很快就崩溃才对啊。。下面的那个代码就是这样子了,单纯的处理数据而已 /// <summary>
            /// 读数据
            /// </summary>
            /// <param name="ar"></param>
            private void ReadThread(TcpClient client)
            {
                Debug.WriteLine("一次连接:");// + name);
                var ns = client.GetStream();
                
                int times = 350;
                string machineId = "";
                
                byte[] buff = new byte[1024 * 8];            try
                {
                    while (IsConnected(client) && !isStop)
                    {
                       
                        if (client.Available == 0)
                        {
                           
                            Thread.Sleep(200);
                            
                            continue;
                        }                    var count = ns.Read(buff, 0, buff.Length);
                        string str = System.Text.Encoding.Default.GetString(buff, 0, count).Replace("\r\n", "").ToUpper();        while (IsConnected(client) && !isStop) 
          估计是这个造成了死循环,
           把 IsConnected 函数发出来,可嫩连接已经断开了,不能判断出来这个函数是这样的: public bool IsConnected(TcpClient tcpClient)
            {
                return tcpClient != null && tcpClient.Connected;
            }
      

  8.   

    public bool IsConnected(TcpClient tcpClient)        {            return tcpClient != null && tcpClient.Connected;        }
    这个函数有错,客户端端口了也检查不到http://zhidao.baidu.com/link?url=nMq1qdMlS9iochxw5PPch1ilFR5UAqJEG6fQ2Za_RN06HGN9dNrQy5dCwetoY-7z9yf8jgxEf_DXUrpoeZNjwa
      

  9.   


    那这个线程是什么时候释放的?我的线程一直在增加执行完就自动释放,你里面是不是写死循环了,贴出来代码不全里面是没有死循环的,因为程序可以执行几天,如果是死循环的话会很快就崩溃才对啊。。下面的那个代码就是这样子了,单纯的处理数据而已 /// <summary>
            /// 读数据
            /// </summary>
            /// <param name="ar"></param>
            private void ReadThread(TcpClient client)
            {
                Debug.WriteLine("一次连接:");// + name);
                var ns = client.GetStream();
                
                int times = 350;
                string machineId = "";
                
                byte[] buff = new byte[1024 * 8];            try
                {
                    while (IsConnected(client) && !isStop)
                    {
                       
                        if (client.Available == 0)
                        {
                           
                            Thread.Sleep(200);
                            
                            continue;
                        }                    var count = ns.Read(buff, 0, buff.Length);
                        string str = System.Text.Encoding.Default.GetString(buff, 0, count).Replace("\r\n", "").ToUpper();        while (IsConnected(client) && !isStop) 
          估计是这个造成了死循环,
           把 IsConnected 函数发出来,可嫩连接已经断开了,不能判断出来这个函数是这样的: public bool IsConnected(TcpClient tcpClient)
            {
                return tcpClient != null && tcpClient.Connected;
            }
     if (client.Available == 0)                    {                                                Thread.Sleep(200);                                                 continue;                    }                     var count = ns.Read(buff, 0, buff.Length);这个判断也不太好,
    直接var count = ns.Read(buff, 0, buff.Length);
    如果count =0 就认为断开了
      

  10.   

    public bool IsConnected(TcpClient tcpClient)        {            return tcpClient != null && tcpClient.Connected;        }
    这个函数判断也有问题,tcpClient.Connected 反应的是上次的状态
    http://zhidao.baidu.com/link?url=nMq1qdMlS9iochxw5PPch1ilFR5UAqJEG6fQ2Za_RN06HGN9dNrQy5dCwetoY-7z9yf8jgxEf_DXUrpoeZNjwa
      

  11.   


    那这个线程是什么时候释放的?我的线程一直在增加执行完就自动释放,你里面是不是写死循环了,贴出来代码不全里面是没有死循环的,因为程序可以执行几天,如果是死循环的话会很快就崩溃才对啊。。下面的那个代码就是这样子了,单纯的处理数据而已
            while (IsConnected(client) && !isStop) 
          估计是这个造成了死循环,
           把 IsConnected 函数发出来,可嫩连接已经断开了,不能判断出来这个函数是这样的: public bool IsConnected(TcpClient tcpClient)
            {
                return tcpClient != null && tcpClient.Connected;
            }
     if (client.Available == 0)                    {                                                Thread.Sleep(200);                                                 continue;                    }                     var count = ns.Read(buff, 0, buff.Length);这个判断也不太好,
    直接var count = ns.Read(buff, 0, buff.Length);
    如果count =0 就认为断开了
    您好,其实这里不是判断client断开的,只是在client没有上报数据的时候让这个线程休眠一会,不然会导致cpu一直被占用,直到占完。
      

  12.   


    那这个线程是什么时候释放的?我的线程一直在增加执行完就自动释放,你里面是不是写死循环了,贴出来代码不全里面是没有死循环的,因为程序可以执行几天,如果是死循环的话会很快就崩溃才对啊。。下面的那个代码就是这样子了,单纯的处理数据而已
            while (IsConnected(client) && !isStop) 
          估计是这个造成了死循环,
           把 IsConnected 函数发出来,可嫩连接已经断开了,不能判断出来这个函数是这样的: public bool IsConnected(TcpClient tcpClient)
            {
                return tcpClient != null && tcpClient.Connected;
            }
     if (client.Available == 0)                    {                                                Thread.Sleep(200);                                                 continue;                    }                     var count = ns.Read(buff, 0, buff.Length);这个判断也不太好,
    直接var count = ns.Read(buff, 0, buff.Length);
    如果count =0 就认为断开了
    您好,其实这里不是判断client断开的,只是在client没有上报数据的时候让这个线程休眠一会,不然会导致cpu一直被占用,直到占完。
    public bool IsConnected(TcpClient tcpClient)        {            return tcpClient != null && tcpClient.Connected;        }
     这个函数判断也有问题,tcpClient.Connected 反应的是上次的状态
     http://zhidao.baidu.com/link?url=nMq1qdMlS9iochxw5PPch1ilFR5UAqJEG6fQ2Za_RN06HGN9dNrQy5dCwetoY-7z9yf8jgxEf_DXUrpoeZNjwa 
    这个呢?你没看?
      

  13.   


    那这个线程是什么时候释放的?我的线程一直在增加执行完就自动释放,你里面是不是写死循环了,贴出来代码不全里面是没有死循环的,因为程序可以执行几天,如果是死循环的话会很快就崩溃才对啊。。下面的那个代码就是这样子了,单纯的处理数据而已
            while (IsConnected(client) && !isStop) 
          估计是这个造成了死循环,
           把 IsConnected 函数发出来,可嫩连接已经断开了,不能判断出来这个函数是这样的: public bool IsConnected(TcpClient tcpClient)
            {
                return tcpClient != null && tcpClient.Connected;
            }
     if (client.Available == 0)                    {                                                Thread.Sleep(200);                                                 continue;                    }                     var count = ns.Read(buff, 0, buff.Length);这个判断也不太好,
    直接var count = ns.Read(buff, 0, buff.Length);
    如果count =0 就认为断开了
    您好,其实这里不是判断client断开的,只是在client没有上报数据的时候让这个线程休眠一会,不然会导致cpu一直被占用,直到占完。请问实际的使用中线程会休眠多久? 如果while sleep 休眠太久是会block 线程的。
    另外,lock (clients) 中间的代码会执行多久?
    你可以在这两段中间插入Interlocked 计数,看看实际的情况如何。 
      

  14.   

    public bool IsConnected(TcpClient tcpClient)        {            return tcpClient != null && tcpClient.Connected;        }
    这个函数判断也有问题,tcpClient.Connected 反应的是上次的状态
    http://zhidao.baidu.com/link?url=nMq1qdMlS9iochxw5PPch1ilFR5UAqJEG6fQ2Za_RN06HGN9dNrQy5dCwetoY-7z9yf8jgxEf_DXUrpoeZNjwa
      

  15.   


    看了,改成这样的代码了,你看看有问题吗?        //修改判断连接的方法
            public bool IsClosed(TcpClient tcpClient)
            {
                bool closed = false;
                byte[] testByte = new byte[1];
                try
                {                //使用Peek测试连接是否仍存在                if (tcpClient.Connected && tcpClient.Client.Poll(0, SelectMode.SelectRead))
                        closed = tcpClient.Client.Receive(testByte, SocketFlags.Peek) == 0;
                }
                catch (SocketException se)
                {
                    closed = true;            }
                return closed;
            }
      

  16.   

    我在想我不要这个lock (clients)可不可以,本来这个clients就只是一个list,用来存放所有的client而已,只是用来记录连接数和最终的一个client的释放,如果我不记录连接数应该就不需要clients,这样就不需要lock方法了,应该是可以的吧?
      

  17.   

    那这个线程是什么时候释放的?我的线程一直在增加执行完就自动释放,你里面是不是写死循环了,贴出来代码不全里面是没有死循环的,因为程序可以执行几天,如果是死循环的话会很快就崩溃才对啊。。下面的那个代码就是这样子了,单纯的处理数据而已
            while (IsConnected(client) && !isStop) 
          估计是这个造成了死循环,
           把 IsConnected 函数发出来,可嫩连接已经断开了,不能判断出来这个函数是这样的: public bool IsConnected(TcpClient tcpClient)
            {
                return tcpClient != null && tcpClient.Connected;
            }
     if (client.Available == 0)                    {                                                Thread.Sleep(200);                                                 continue;                    }                     var count = ns.Read(buff, 0, buff.Length);这个判断也不太好,
    直接var count = ns.Read(buff, 0, buff.Length);
    如果count =0 就认为断开了
    您好,其实这里不是判断client断开的,只是在client没有上报数据的时候让这个线程休眠一会,不然会导致cpu一直被占用,直到占完。这里不要使用Thread.Sleep(200)。使用timer。
      

  18.   

    我在想我不要这个lock (clients)可不可以,本来这个clients就只是一个list,用来存放所有的client而已,只是用来记录连接数和最终的一个client的释放,如果我不记录连接数应该就不需要clients,这样就不需要lock方法了,应该是可以的吧?
    如果一定要使用lock的话,建议使用.net 4.5 里面的 SemaphoreSlim.WaitAsync()
      

  19.   

    我在想我不要这个lock (clients)可不可以,本来这个clients就只是一个list,用来存放所有的client而已,只是用来记录连接数和最终的一个client的释放,如果我不记录连接数应该就不需要clients,这样就不需要lock方法了,应该是可以的吧?  我认为lock还是有必要的,不过你的代码不够“漂亮”,
       应该尽量减少Lock 的时间
       也就是说与clients无关的操作应该放到lock之外
        
        与clients无关操作。。
        lock(clients)
       {  
       }
        还有 你clients是什么类型的,建议使用hasttalbe,
       那么你判断是否存不存在就不用循环了 ,直接用clients[mid]就可以了
        
      

  20.   

     > 不过你的代码不够“漂亮”,楼上真客气,这代码,不入流的初级程序员的简单粗暴的COPY-PASTE,
    实在是烂的可以,读得我头痛。找个入门的人重写好了。
      

  21.   


    看了,改成这样的代码了,你看看有问题吗?        //修改判断连接的方法
            public bool IsClosed(TcpClient tcpClient)
            {
                bool closed = false;
                byte[] testByte = new byte[1];
                try
                {                //使用Peek测试连接是否仍存在                if (tcpClient.Connected && tcpClient.Client.Poll(0, SelectMode.SelectRead))
                        closed = tcpClient.Client.Receive(testByte, SocketFlags.Peek) == 0;
                }
                catch (SocketException se)
                {
                    closed = true;            }
                return closed;
            }
            直接这样不可以吗?
         try
    {
       return  tcpClient.Client.Poll(100, SelectMode.SelectRead);//100毫秒
    }catch
    { return false;
    }
    SocketFlags.Peek这个我没用过
    tcpClient.Client.Receive(testByte, SocketFlags.Peek)