TCP多线程还没多少经验,希望大家能帮我找找我的问题出在哪儿。谢谢大家了

解决方案 »

  1.   

    哦,你这样是不行的。你的客户端是不是每次都重连啊?如果是常连接的话。每个客户端用一个socket。客户端不要反复创建socket去连接服务端。你有多少个客户端那?
      

  2.   

    我的思路是这样的,一旦有数据过来,我就识别这些是不是我的客户端,如果是的话,就给其分配一个线程,保持长连接(这个是必须的)。如果有一千个客户端和我连接,我就要分配一千个线程。呵呵。现在的问题是,我的资源好像浪费的太厉害了。虚拟内存增加到一定程度(达到700M左右的时候),程序就OVER了
      

  3.   

    1000个是不可能做长连接的。先不说1000个socket的资源占用问题。光是切换线程时的开销就大的不得了。我不知道为什么不能用短连接?你的客户端不是自己写的?
      

  4.   

    除了实时看到设备的状态外,也要对这些设备进行实时的控制。就像要给设备发送一个命令一样。所以必须要用长连接。因为像这种做法,我见到过成功的项目。他的大概可以同时保持1800个连接吧。现在我的问题就是,我的虚拟内存猛增,我受不了呀。要如何才能解决虚拟内存增多的问题。我在程序中,用的最多的是byte[] buffer=new byte[512]。也就是while(true)里面每接收一次数据,都要重新定义一下buffer,也不知道与这有没有关系 
      

  5.   

    呃1800,那性能会差的要死的。你加内存吧,换成64位系统。你为什么不能在客户端开监听端口,然后服务端反向去连呢?1800个线程,我是没见过这么干的。。内存猛增很正常,.net就是这样,700m挂不掉的,我以前做的可以上到3.4g这个极限,照样可以运行。如果确认是内存问题的话,考虑写个内存池吧。
      

  6.   

    fskang兄,你以前做的那个能够达到3.4G的程序,指的是虚拟内存还是内存?
      

  7.   

    多线程的确挺复杂的,NEW就多出上十个线程。限制线程并发数吧
    http://www.cnblogs.com/surfsky/archive/2008/12/12/1353437.html
      

  8.   


    呵呵,虚拟内存1.7g。32位系统的4gb上限。我还是不太相信会有人用1800个线程去跑。你确信?
      

  9.   

    工作集的问题吧。上午简单写了一个对象池。.net framework4下的。随手写的可能有bug。直接上代码:using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections.Concurrent;
    using System.Collections.Generic;namespace ObjectPoolConsole
    {
        class BufferPool
        {
            private ConcurrentStack<byte[]> _stack;
            private int _size;
            private int _allocationCount;        public BufferPool(int size) 
            {
                _size = size;
                _stack = new ConcurrentStack<byte[]>();
            }        public int Size
            {
                get { return _size; }
            }        public int AllocationCount
            {
                get { return _allocationCount; }
            }        public int Count
            {
                get { return _stack.Count; }
            }        public byte[] Take()
            {
                byte[] result;
                if (_stack.TryPop(out result)) 
                {
                    return result;
                }
                //池分配
                System.Threading.Interlocked.Add(ref _allocationCount, 1);
                return new byte[_size];
            }        public void Return(byte[] buffer)
            {
                _stack.Push(buffer);
            }
        }    class BufferManager
        {
            private BufferPool[] _pools;
            private int[] _poolSizes;
            public BufferManager(int maxBufferSize)
            {
                System.Diagnostics.Debug.Assert(maxBufferSize >= 128);            //最小分配大小为128个字节。
                long bufferSize = 128;
                var list = new List<BufferPool>();
                while (bufferSize < maxBufferSize) 
                {
                    list.Add(new BufferPool((int)bufferSize));
                    bufferSize *= 2L;
                }
                list.Add(new BufferPool(maxBufferSize));            _pools = list.ToArray();
                _poolSizes = new int[_pools.Length];
                for (int i = 0; i < _pools.Length; ++i) {
                    _poolSizes[i] = _pools[i].Size;
                }
            }        public int PoolBufferCount 
            {
                get 
                {
                    int result = 0;
                    foreach (var pool in _pools) 
                    {
                        result += pool.Count;
                    }
                    return result;
                }
            }        public int PoolAllocationCount
            {
                get
                {
                    int result = 0;
                    foreach (var pool in _pools)
                    {
                        result += pool.AllocationCount;
                    }
                    return result;
                }
            }        public byte[] TakeBuffer(int size)
            {
                BufferPool pool = FindBufferPool(size);
                if (pool != null) 
                {
                    pool.Take();
                }
                //大对象直接分配。
                return new byte[size];
            }        public void ReturnBuffer(byte[] buffer)
            {
                BufferPool pool = FindBufferPool(buffer.Length);
                if (pool != null) 
                {
                    pool.Return(buffer);
                }
            }        private BufferPool FindBufferPool(int bufferSize)
            {
                for (int i = 0; i < _poolSizes.Length; ++i) 
                {
                    if(bufferSize <= _poolSizes[i])
                    {
                        return _pools[i];
                    }
                }
                return null;
            }
        }
    }
    测试代码:using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;namespace ObjectPoolConsole
    {
        class Program
        {
            static BufferManager manager = new BufferManager(1024);        static void Main(string[] args)
            {            List<Thread> list = new List<Thread>();
                for (int i = 0; i < 1000; i++) 
                {
                    Thread t = new Thread(AllocBuffer);
                    list.Add(t);
                    t.Start();
                }            foreach (Thread t in list) 
                {
                    t.Join();
                }            Console.WriteLine("创建Buffer的个数为:{0}", manager.PoolBufferCount);
                Console.WriteLine("分配Buffer的次数为:{0}", manager.PoolAllocationCount);
                Console.ReadLine();
            }        static void AllocBuffer() {
                Random r = new Random();
                int size = r.Next(1024);
                var buffer = manager.TakeBuffer(size);
                r.NextBytes(buffer);
                Thread.Sleep(1000);
                manager.ReturnBuffer(buffer);
            }
        }
    }这里提供了一个简单的Buffer池框架。很多控制方面的东西都没加。