按照http://support.microsoft.com/kb/140527/en-us的解决方法如下:
void CTransmitServerDlg::ProcessPendingAccept()
{
   CServerToClientSocket* pSocket = new CServerToClientSocket();
   if (m_pListenSocket.Accept(*pSocket))
   {
   CClientThread* pClientThread =(CClientThread*)AfxBeginThread(RUNTIME_CLASS(CClientThread),THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED);
pClientThread->hConnected = pSocket->Detach(); //SOCKET hConnected;在CClientThread中定义
pClientThread->ResumeThread();
   }
}
BOOL CClientThread::InitInstance()
{  pClientSocket->Attach(hConnected); }
但是还是有这个错误,不知道为什么?
同时在服务器退出,运行到pClientThread->pClientSocket->Close();在这里出现异常:
void PASCAL CAsyncSocket::KillSocket(SOCKET hSocket, CAsyncSocket* pSocket)
    {
            ASSERT(CAsyncSocket::LookupHandle(hSocket, FALSE) != NULL);
这两个问题这么了好久,请高手帮忙解答,如果分数不够解决后另外给分,多谢。

解决方案 »

  1.   

    不要用MFC干这个,改用WINSOCK的API。
      

  2.   

    我也遇到过同样的问题,你可以用如下的方法来试试:首先在CClientThread类中放置一个你的ClientSocket对象,也就是把你的hConnected句柄换成对象,然后通过以下语句来设置:
    ......
    server.Accept((CSocket&)m_ClientSocket);
    pClientThread->m_ThreadSocket=&m_ClientSocket;
    pClientThread->m_ThreadSocket->Attach(m_ClientSocket.Detach(),FD_READ|FD_CLOSE);
    .......
      

  3.   

    我想问一下几个问题,
    你是将pSocket = new CServerToClientSocket();中的pSocket地址赋给线程中的m_ThreadSocket么?m_ThreadSocket是线程中通讯的指针么?我那里的hConnected只是句柄帮定功能而已.
    还有你这个Attach函数调用是在CTransmitServerDlg中,还是在CClientThread::InitInstance()中?现在没有环境,明天试试看行不行.
      

  4.   

    1.你是将pSocket = new CServerToClientSocket();中的pSocket地址赋给线程中的m_ThreadSocket么?
    是的,C++中默认是没有办法把对象用等号付值的,除非你重载等号
    2.m_ThreadSocket是线程中通讯的指针么?我那里的hConnected只是句柄帮定功能而已
    是的,更准确的说是CSocket(或它的超类或子类)的指针
    3.还有你这个Attach函数调用是在CTransmitServerDlg中,还是在CClientThread::InitInstance()中?
    是在CTransmitServerDlg中设置的(我是这样做的,是不是能在CClientThread::InitInstance()中设置我还真不知道,没有试过,你可以试一下)
      

  5.   

    试了一下,第二个问题已经解决,非常感谢,但是第一个还是有这个错误,我是这样写的,你看有没有问题,多谢!
    CServerToClientSocket *pSocket = new CServerToClientSocket;
    if (m_pListenSocket.Accept(*pSocket))
    {
       CClientThread* pClientThread =(CClientThread*)AfxBeginThread(RUNTIME_CLASS(CClientThread),THREAD_PRIORITY_NORMAL,0, CREATE_SUSPENDED);
       pClientThread->m_pThreadSocket = pSocket;
       pClientThread->m_pThreadSocket->Attach(pSocket->Detach());
       DWORD aa = pClientThread->ResumeThread();
    }
    class CClientThread : public CWinThread
    {
       CServerToClientSocket *m_pThreadSocket;
    }
      

  6.   

    pSocket设置成类的公共(或私有)成员(对整个类可见),不然可能会有问题;还有就是这个方法有个局限性,就是如果要接受很多客户端连接的话,就要事先申明一个很大的Socket数组,对于这个我还没有解决方案,你试一下,如果能行的通的话,可否告诉我一个解决方案.
      

  7.   

    还有就是要在你要在Socket关闭时向你的CClientThread发线程退出消息:PostThreadMessage(hThread,0,.....)
      

  8.   

    http://support.microsoft.com/kb/175668/en-usHow to pass a socket connection between threads in an MFC application in Visual C++
      

  9.   

    pSocket是一个指针而不是指针数组,设置为类的成员变量后问题依然存在,这个问题都郁闷了俺一个多星期了,我的qq是:284039924,我想让你帮我看看,对不对,多谢.
      

  10.   

    CServerToClientSocket pSocket;
    if (m_pListenSocket.Accept((CServerToClientSocket*)&pSocket))
    {
       CClientThread* pClientThread =(CClientThread*)AfxBeginThread(RUNTIME_CLASS(CClientThread),THREAD_PRIORITY_NORMAL,0, CREATE_SUSPENDED);
       pClientThread->m_pThreadSocket = &pSocket;
       pClientThread->m_pThreadSocket->Attach(pSocket->Detach());
       DWORD aa = pClientThread->ResumeThread();
    }
    如上试试?我不经常上QQ,发到我邮箱[email protected]
      

  11.   

    我的代码如下:
    server.Accept((SocketClient&)client);

    pThread=(SocketThread*)::AfxBeginThread(RUNTIME_CLASS)(SocketThread)                                                                                                           THREAD_PRIORITY_NORMAL,    0,
                                  CREATE_SUSPENDED);
    pThread->m_Socket=&client; //*********************************************
    pThread->m_Socket->Attach(client.Detach(),FD_READ);
    //********************************************** pThread->ResumeThread();顺利通过测试
      

  12.   

    我这个程序是和硬件帮定的,到你那里可能不能发现错误.你说pSocket是类的全局变量的话,那么他的地址不会变化,所以到第二个客户端运行到if (m_pListenSocket.Accept((CServerToClientSocket*)&pSocket)),我试了下会出现错误,除非定义多个pSocket才行.我发给你看你能不能发现什么问题,多谢。
      

  13.   

    推荐一个做法是定义一个Socket数组(不需要很大,大概和你实际使用差不多就好了),然后定义一个数据结构,用这个数据结构来管理这些socket(有连接就分配,连接关闭就释放,供下次连接使用),方法类似于链表和对象数组(JAVA中的ArrayList等类).我没有实际做过,你可以参考一下.
      

  14.   

    我发现我的问题不在这里了,而是在pClientThread线程中虽然将m_pThreadSocket进行帮定后,但是在一个回调函数中
    int _cdecl EnterVideoStream(void* ptr, char* buff, int length)
    {
        aa = mClientInfoNode.pCleintThread->m_pThreadSocket->Send(bufftmp,ilen,0);
    }
    该回调函数也是一个线程,所以我在又一个线程中使用了m_pThreadSocket,出现了这个错误,现在是在第三个线程中使用套接字,请问有没有办法将句柄关联到这个回调函数中来呢?
      

  15.   

    我提供一个用来管理Socket的数组类,使用的是MFC的CObArray类,你研究一下在使用,我就是用它,再加上一个CWinThread类的继承类创建的线程来工作,很好使用,我调试过了:
    头文件:
    #include "MySocket.h"class CSocketArrayList
    {
    private:
    DWORD m_index;//内部计数器
    DWORD m_Limit;//对象数量限制计数器
    CMySocketClient *m_Socket;//一个继承了CAnsynSocket的子类,在MySocket.h中定义
    CObArray socketList;//Socket管理数组public:
    /*********************************************/
    /*         构造函数,初始化内部数组大小      */
             /* 参数说明:len 要初始化的大小,默认是10    */
    /*********************************************/
    CSocketArrayList(DWORD len=10);
    ~CSocketArrayList();
    /*********************************************/
    /*                  得到 Socket              */
    /*参数index :添加成功后返回的索引值         */
    /*如果成功设置,返回CMySocketClient对象指针,否则返回NULL*/
    /*********************************************/
    CMySocketClient * getSocket(int *index);
    /*********************************************/
    /*         根据ID删除Socket                  */
             /* 参数说明:hSocket Socket 句柄             */
    /*如果成功设置,返回TRUE,否则返回FALSE      */
    /*********************************************/
    BOOL deleteSocket(SOCKET hSocket);
    /* 返回当前元素个数*/
    DWORD getCount();
    };
    程序文件:
    #include "stdafx.h"
    #include "SocketArrayList.h"CSocketArrayList::CSocketArrayList(DWORD len)
    {
    //socketList.SetSize(len);
    m_Limit=len;//设置对象数量限制
    m_index=0;
    }
    CMySocketClient * CSocketArrayList::getSocket(int *index)
    {
    if(m_index>m_Limit)
    return NULL; m_Socket=new CMySocketClient();
    int index_socket=socketList.Add((CObject*)m_Socket);//将Socket添加到管理数组中
    TRACE("getSocket函数:当前Socket数组中有%d个Socket连接!\n",socketList.GetSize());
    *index=index_socket;//将索引通知调用函数
    m_index++;//对象计数器加一
    return m_Socket;
    }
    BOOL CSocketArrayList::deleteSocket(SOCKET m_hSocket)
    {
    int m_size=socketList.GetSize();
    for(int i=0;i<m_size;i++)
    {
    CMySocketClient *pThisSocket=(CMySocketClient *)socketList.GetAt(i);
    if((pThisSocket!=NULL)&&(pThisSocket->m_hSocket==m_hSocket))
    {
               pThisSocket->Close();//关闭这个Socket
      socketList.RemoveAt(i);//从管理数组中删除这个对象
      //delete pThisSocket;
    TRACE("deleteSocket函数:当前Socket数组中还有%d个Socket连接!\n",socketList.GetSize());
      m_index--;
      return TRUE;
    }
           }
    return FALSE;
    }
    DWORD CSocketArrayList::getCount()
    {
    return socketList.GetSize();
    }
    CSocketArrayList::~CSocketArrayList()
    {
    int m_size=socketList.GetSize();
    for(int i=0;i<m_size;i++)
    delete socketList.GetAt(i);
    }
      

  16.   

    建议你用继承CWinThread类的方式来创建线程,这样你可以直接串SOCKET句柄,然后在CWinThread类的继承类中的重载InitInstance函数中用如下语句来完成绑定,你最后一次提到的问题,也可以如此解决:
             CMySocketClient *m_pClient;
             m_pClient=new CMySocketClient();
    m_pClient->Attach(m_hSocket,FD_READ|FD_CLOSE);
    调试过,可以工作.