正在编写服务器端程序,考虑到一个问题请大家指教!不知道是使用异步SOCKET,还是线程池,还是二者能和在一起用,(有点白,主要是对异步SOCKET理解不够)!详细问题请继续:外部对服务器的访问及数据交互总是随时随刻的,使用BeginSend/BeginReceive时总是会再创建一个线程用于EndSend/EndReceive,当有很多客户端同时和服务器进行数据交互时,那么服务器端必要会开启很多个线程,那么怎么对这些线程进行管理呢?然后就看到使用线程池对线程进程管理的相关文章,同时也了解到异步SOCKET好像是自己就有线程池进行管理,这里就期待高手帮我搞清楚了!⊙﹏⊙b汗!那么问题来了:
1、为了不把服务器累死,我想在进行网络异步通信时,是否需要对服务器线程进行管理?
2、如果异步通信有管理,那我们应该就是否不需要管理了?(这个问题有点白,主要是为了第三个问题)
3、如果没有,那么是否通过线程池进行管理,如何管理?线程池通过QueueUserWorkItem使线程去执行事件,而异步的BeginSend/BeginReceive好像直接开启了一个线程去运行回调函数!

解决方案 »

  1.   

    对于超多连接,线程池是必要的,一般线程的数量为cpu数量的2倍,C#不是有线程池的类吗,你还可以通过IO完成端口实现,windows有内置的线程池,可以满足大多数的要求
      

  2.   

    线程池是知道的!
    可有人说应该同步+线程池,因为C#的SOCKET的异步通信是基于类似完成端口的,其内部已经进行过优化,因此不需要线程池!不知道这是否正确?
      

  3.   

    1、为了不把服务器累死,我想在进行网络异步通信时,是否需要对服务器线程进行管理?不用,异步操作时无法得到线程资源的回调方法产生的线程任务会自己排在任务队列中,等待CLR线程池中有空闲线程资源。服务器累不死。当然默认的线程池上下限最好还是调整一下。2、如果异步通信有管理,那我们应该就是否不需要管理了?(这个问题有点白,主要是为了第三个问题)不需要,通常不应当在异步回调方法中调用会产生阻塞调用。因为线程被阻塞后是没办法从外边停下的(scocket阻塞读的时候可以直接关socket,让线程的阻塞产生错误,跳出)。3、如果没有,那么是否通过线程池进行管理,如何管理?线程池通过QueueUserWorkItem使线程去执行事件,而异步的BeginSend/BeginReceive好像直接开启了一个线程去运行回调函数!通过线程池进行管理?没明白什么意思,你用QueueUserWorkItem使线程去执行事件和异步回调做的工作是一模一样的。不排除你为了炫技非要把线程池调用写出来。但确实没有必要,用异步就行了。另外异步和线程池都不是去开启一个线程,而是去线程池中申请一个线程。你要维护CLR线程池的大小也没问题的。只不过也就是设点参数什么的。任务的线程调度是异步机制来完成的,不用你去处理。
      

  4.   

    我现在现在已经在写了,下面是我RECEIVE的初期代码
          
      private void ReceiveCallback(IAsyncResult ar)
            {
                State_Object so = (State_Object)ar.AsyncState;
                int byteread = 0;
                Socket socket = so.workSocket;
                try
                {
                    byteread = socket.EndReceive(ar);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
                if (byteread > 0)
                {
                    int oldlength = tempbuffer.Length;
                    //扩充
                      Array.Resize(ref tempbuffer, (oldlength + byteread));
                    Buffer.BlockCopy(so.buffer, 0, tempbuffer, oldlength, byteread);
                        lock (x)
                        {
                             ReceiveCompose(tempbuffer);
                        }
                }
                else
                {
                    Console.WriteLine("连接断开");
                }
                //开始继续接收
                ReceiveInternal(socket);
            }其中  ReceiveCompose(tempbuffer);
    就表示处理数据落!我这里就有疑惑了,因为ReceiveCompose这个函数未来可能会进行很复杂的计算,如果还没计算完就又收到数据要求进行分析计算,会不会发生冲突!?
    还是说每次接受到数据都会再一个线程运行ReceiveCallback函数中的代码!?
    期待解答,谢谢!~
      

  5.   

    还是说每次接受到数据都会再申请一个线程去运行ReceiveCallback函数中的代码!?笔误,笔误,嘿嘿!~
      

  6.   

    还是说每次接受到数据都会再申请一个线程去运行ReceiveCallback函数中的代码!?是的。另:有时序要求的计算是不适合多线程的。
      

  7.   

    这个倒没有时序,只是每次收到数据后都会有一次分析计算,然后给客户反馈结果。另外我看有的说同一段代码被多个线程同时调用会出现错误,需要LOCK,对于我这种情况,需要吗?
    我个人理解的是,每次接受到数据然后就运行ReceiveCompose去处理,它们是一种并行处理的模式,应该不需要LOCK?对吗?
      

  8.   

    是啊!您真是内行啊~确实不是计算机专业的,只是现在每个行业都需要计算机啊!所以都要我们去半路学习,没经过系统的学习,感觉确实不行,我们挺多是写个小程序,毕竟那只需要会编写程序就OK啦。现在随着项目的要求增加,就发现远不是仅仅知道一门编程语言,知道几个API函数就够了的!
      

  9.   

    。Net从哪个版本开始支持IOCP了?
      

  10.   

    另外,如果将来在自定义的ReceiveCompose函数处理中,会涉及到公用变量或数据库数据的调用,按您说的那么就可能出来脏读或溢出的问题!这个时候我该怎么处理呢?我的理解是,我应该使用LOCK锁住这个读取过程,并将值赋给局部变量,然后释放以供其它线程读取,再实现局部变量在ReceiveCompose函数中继续分析计算,对吗?
      

  11.   

    必须lock, 如果我自己做的话, 我会这样做一个class, 中保存了socket类, 一个object, 
    一个处理方法, 创建多个线程去执行这个方法, 这个
    方法循环每个class, 先获取class中的object是否处在lock状态下, 如果不在这个状态, lock, 获取class中的socket类是否有需要处理的数据, 有的话处理. 然后结束lock, 继续循环下一个class这样就能保证多个线程不会同时操作socket
      

  12.   

    一些高手的博客中提到的江湖传说.net中的socket异步用的是IOCP,可信度还是有的。
      

  13.   

    是的,但不是锁读取过程,是锁一个对象。锁只是一个标记。你设置一个 object a = new object()。
    用的时候
    lock(a)
    {
    读数据AAA
    }用一个类来封装。a做为一个私有属性,各种数据操作方法中都锁这个a就行了。
      

  14.   


    这个我是看了哪个美国佬的书知道的,Network+Programming+for+Microsoft+Windows+2nd.CHM
    里面说了C#是使用的类似于完成端口的
      

  15.   

    反编译下,或者找到.net2.0的源代码就可以看到
    Socket异步可以指定使用完成端口3.5支持高性能异步通信,以Asy开头的系列函数
      

  16.   

    看一下这个帖子http://blog.csdn.net/hulihui/archive/2008/11/07/3244520.aspx
    完整项目代码可以搜索一下SuperSocket。