我看了看普遍的做法似乎都是由CAsyncSocket派生两个类,一个Listen用来监听客户端连接,另一个Request用来处理客户端请求
  void   CListenSocket::OnAccept(int   nErrorCode)     
  {   
  CRequestSocket   *pRequest   =   new   CRequestSocket   ;     
  if(   !pRequest)   
  return   ;     
    
  if   (   Accept(   *pRequest   )   )   
  {   
  pRequest->AsyncSelect(   FD_READ|FD_CLOSE);   
  }   
    
   CAsyncSocket::OnAccept(nErrorCode);   
  }
我还是不太了解,这意思是不是说,Listen只负责监听端口,当有新连接的时候,就new一个Request出来,然后怎样响应客户端的请求,就是Request的事情了(比如CRequestSocket::OnReceive里处理客户端发来的东西,等等)如果是这样,那么在CListenSocket::OnAccept中new的Request,当连接断开后,它就是无用的了,如果不释放掉它不就是内存泄露了吗?毕竟MFC没有C#的Garbage Collector特性请各位释疑,如果我的想法不正确,请大家讲讲一般通用的办法,如何用CAsyncSocket做支持多个客户端连接的服务端?

解决方案 »

  1.   

    就这种最简单的服务端,用了CAsyncSocket,还需要多线程?
    我的问题是 new出来的东西,断开连接后就不就没用了?那谁来回收它?
    一般的方法是怎么做的?
      

  2.   

    那么在CListenSocket::OnAccept中new的Request
    1.
    可以将客户端的套接字保存在一个链表中:
    CPtrList m_connectionList;  
    m_connectionList.AddTail(pSocket);//保存该套接字
    2.
    在OnDestroy()中释放监听套接字和new出来的客户端套接字
    if (m_pListeningSocket)
    {
    delete m_pListeningSocket;
    m_pListeningSocket=NULL;
    }
    //清除链表中所有客户端的套接字
    int nSocketNum=m_connectionList.GetCount();
      

  3.   

    是在ListeningSocket在OnDestory()的时候才释放new出来的CAsyncSocket?
    一般ListeningSocket都Destory了,那就是关闭服务端了啊,在服务端都关闭的时候还有必要考虑释放这些吗?
    能否做到每个客户端断开连接后,释放为他new的CAsyncSocket?
      

  4.   

    重载OnClose函数delete this。
      

  5.   

    在OnClose的时候释放动态创建的对象。
    但是,作为服务器端程序,为避免频繁分配和释放内存造成的性能降低以及内存碎片问题,动态创建的对象应该是基于对象池概念的,该对象所属的类型应该重载new和delete操作符,使之并不是直接分配和释放内存,new的时候先从对象池里取可用对象,如果取不到,再分配内存并把新建的对象放入对象池中,delete的时候将对象池中对应的不用的对象置为可用。
    当然,上面说的是按高负荷服务器设计要求来说的,作为普通科研级别的习作可以忽略这个。
      

  6.   

    你肯定要找个list之类的记录一下这个socket
    因为onclose只有在对方关闭的时候能收到,本方关闭连接的时候你得自己处理关闭和delete
      

  7.   

    直接在OnClose函数delete this可行吗?这不是要自己删除自己吗?
    这样做好些:new的时候将新对象指针加入到一个链表中(比如窗口类中的链表),OnDestory的时候给窗口post一个消息,参数包含这类的指针,一定要post不能send,因为post是异步的,窗口收到这个消息,延时若干毫秒后,删除该对象,将其指针链表正如8楼所说,频繁分配、释放内存是不好的,记得我们在只用套接字而不是封装好的类的时候是怎么做的吗?对!定义一个用于与客户端连接的套接字数组,新有客户端连接的时候,给他们分配可用的套接字,这个数组就是“对象池”的概念,但数组的容量是固定的,你的设计应该可以在容量不足的时候使这个对象池的容量扩大,这样就可以动态的维护与多个客户端的连接,并且避免频繁的内存分配
      

  8.   

    具体一点的做法,用一个链表存储Socket对象指针,初始创建一定数量的对象,比如50个
    然后再来一个队列,这个队列保存可用的(空闲的,未与客户端连接的)Socket对象指针,那么初始时全部的指针都入队列
    当一个客户端请求连接的时候,出队列一个对象分配给这个客户端,比如10个。若是队列为空,那就说明当前所有的Socket对象都被用了,这时就创建一定数量的新Socket,将指针保存到列表,并入队列,这样就保证如果不够用的情况下会分配新的对象。
    当一个用户断开连接的时候,将这个对象的指针重新入队列,这样用过的Socket对象就可以重复使用了这应该就是一个比较合理的方案了