mfc编程,服务器端建立socket监听,然后客户端connect触发服务器端的onaccept,开新socket,之后客户端发送登陆数据,触发服务器端onreceive,完成登陆之后客户端关闭socket,触发服务器端onclose,服务器端也关闭socket。因为使用的堵塞模式,所以一个用户登录的时候别人要等待。于是相加子线程,只是以前没用过多线程,今天看了一天大概了解了一些。大概觉得是要在onaccept或是onreceive函数中开子线程,不知道对不对?如果不对,该怎么办呢?挺急的,请指导。谢谢!!

解决方案 »

  1.   

    或者是使用select模型是不是可以避开多线程的问题?
      

  2.   

    每当服务器Accept的时候开线程去和此SOCKET交涉或者IOCP
      

  3.   

    onaccept之后,就开多线程,处理收发数据操作
      

  4.   

    要开多线程可以这样:
    accept在主线程里面跑,得到一个连接socket后开一条线程,然后传递socket到新线程中,在新线程中进行recv即可
    select可以避免每个连接开一个socket,但是一个select在windows下正常只能轮循64个socket,你的连接要是多话,可能还是需要开多线程处理.其实你完全可以使用异步socket处理
      

  5.   

    那您的意思是说把onreceive就放弃掉了?直接在onaccept里调用堵塞的接收函数?
      

  6.   

    阻塞了你程序办?
    阻塞模式编程 一个线程来管理客户连接 连接进来用新的SOCKET创建线程,这个线程来管理用户发送过来的信息和关闭连接信息,这样WHILE 下去。
    至于发送 看你自己了。
    不过阻塞模式的多线程个人不喜欢!
      

  7.   

    本人对mfc一直没有理论研究,只是现学现用,麻烦大家帮忙看看我加了新线程的这个,怎么样。谢谢
    void CListenSocket::OnAccept(int nErrorCode) 
    {
    AfxBeginThread(thread,0);
    CSocket::OnAccept(nErrorCode);
    }
    UINT thread( LPVOID p )
    {CRequestSocket *temp=new CRequestSocket;
    g_SocketFunction.AcceptClient();
    g_SocketFunction.ReceiveData(temp);
    g_SocketFunction.DetectClientClose(temp);
    AfxEndThread(0);
    return 0;
    }
    unsigned char CSocketFunction::AcceptClient()
    {
    CString m_strContent; CString m_strSocketIP;
    UINT m_uiSocketPort; CRequestSocket* m_pRequestSocket = new CRequestSocket; if(!(m_ListenSocket.Accept(*m_pRequestSocket)))
    {
    m_pRequestSocket->Close();
    m_strContent = "Error to accept the client!\r\n";
    g_pServerDoc->ShowLog(m_strContent);
    return 0;
    } g_pServerDoc->ShowLog("\r\nOK to accept one client!\r\n");

    char buffer[8];

    if(m_pRequestSocket->GetSockName(m_strSocketIP,m_uiSocketPort) == 0)
    g_pServerDoc->ShowLog("Error to get IP and Port!\r\n");
    else
    {
    m_strContent = " Server IP is ";
    m_strContent += m_strSocketIP;
    m_strContent += " Server Port is ";
    m_strContent += ltoa(m_uiSocketPort,buffer,10);
    m_strContent += "\r\n";
    g_pServerDoc->ShowLog(m_strContent);
    }

    if(m_pRequestSocket->GetPeerName(m_strSocketIP,m_uiSocketPort) == 0)//执行到这会出现User breakpoint called from code at 0x7c921230 的提示,以及unhandled exception....的错误。不知道这种错误应该怎么找到原因。百度的改注册表不好使
    g_pServerDoc->ShowLog("Error to get Client IP and Port!\r\n");
    else
    {
    m_strContent = " Client IP is ";
    m_strContent += m_strSocketIP;
    m_strContent += " Client Port is ";
    m_strContent += ltoa(m_uiSocketPort,buffer,10);
    m_strContent += "\r\n";
    g_pServerDoc->ShowLog(m_strContent);
    }
    m_pLastRequestSocket = m_pRequestSocket; return 1;
    }
    unsigned char CSocketFunction::ReceiveData(CRequestSocket* m_pRequestSocket)
    {
    ...
    }
    unsigned char CSocketFunction::DetectClientClose(CRequestSocket* m_pRequestSocket)
    {
    CString m_strContent;
    CString m_strSocketIP;
    unsigned int m_uiSocketPort;
    char buffer[8]; CTime CurrentTime = CTime::GetCurrentTime(); 

    CString szTime = CurrentTime.Format("'%Y-%m-%d %H:%M:%S'"); g_pServerDoc->ShowLog("\r\nA Client want to close at   "+szTime+"  !\r\n"); if(m_pRequestSocket->GetSockName(m_strSocketIP,m_uiSocketPort) == 0)
    g_pServerDoc->ShowLog("Error to get IP and Port!\r\n");
    else
    {
    m_strContent = " Server IP is ";
    m_strContent += m_strSocketIP;
    m_strContent += " Server Port is ";
    m_strContent += itoa(m_uiSocketPort,buffer,10);
    m_strContent += "\r\n";
    g_pServerDoc->ShowLog(m_strContent);
    }

    if(m_pRequestSocket->GetPeerName(m_strSocketIP,m_uiSocketPort) == 0)
    g_pServerDoc->ShowLog("Error to get IP and Port!\r\n");
    else
    {
    m_strContent = " Client IP is ";
    m_strContent += m_strSocketIP;
    m_strContent += " Client Port is ";
    m_strContent += itoa(m_uiSocketPort,buffer,10);
    m_strContent += "\r\n";
    g_pServerDoc->ShowLog(m_strContent);
    }

    m_pRequestSocket->Close();
    delete m_pRequestSocket;
    m_pRequestSocket = NULL; g_pServerDoc->ShowLog("OK to Close!\r\n");
    if(m_pLastRequestSocket == m_pRequestSocket)
    m_pLastRequestSocket = NULL; return 1;
    }
      

  8.   

    void CListenSocket::OnAccept(int nErrorCode)  
    {
    AfxBeginThread(thread,0);
    CSocket::OnAccept(nErrorCode);
    }我没用过MFC的SOCKET,不过很确定你这样的写法是错的!