请教大家在服务程序中(windows服务程序,没有窗口的那种),能否接收(或是触发)winsock消息,例如:能够触发OnAccept,如果能,应该怎样做。我的程序是这样的,从CAsyncSocket类继承了一个新的类,在该类中处理winsock事件。在对话框测试中,都很正常,包括心跳包等都测试通过,但在服务程序中,只能建立连接,没有触发OnAccep(但是客户端显示连接上了),请教大家,这是为什么?

解决方案 »

  1.   

    CAsyncSocket需要创建一个窗口的阿,是系统自己创建的
    可以考虑用一个线程,用wsaselect帮定SOCKET的事件,用WSAFORMUTIPLEOBJECT来检视有没有网络时间,用WSAEnumNetworkEvents来确定是哪个网络消息
      

  2.   

    以下是我在pda上面用倒的,可以参考
    DWORD CTCPClientCE::SocketThreadFunc(LPVOID lparam)
    {
    char recvBuf[1024];
    int recvLen;
    int   nNetRet = 0;
    int iError = 0;
    DWORD dwRet = WSA_WAIT_EVENT_0;
    CString strErr; CTCPClientCE *pSocket; WSANETWORKEVENTS netEvents;
    //得到CTCPClientCE实例指针
    pSocket = (CTCPClientCE*)lparam;
    //定义读事件集合
    for(;;)
    {
    dwRet = WSAWaitForMultipleEvents(2, pSocket->m_hWSAEvent, FALSE, WSA_INFINITE, FALSE); switch(dwRet)
    {
    case WSA_WAIT_EVENT_0:
    CloseHandle(pSocket->m_tcpThreadHandle);
    pSocket->m_tcpThreadHandle = NULL;
    return 0;
    case WSA_WAIT_EVENT_0 + 1://fd_read
     //网络事件的消息

    memset(&netEvents, 0, sizeof(WSANETWORKEVENTS));
    nNetRet = WSAEnumNetworkEvents(pSocket->m_socket, pSocket->m_hWSAEvent[1], &netEvents); if(nNetRet != 0)
    {
    WSAResetEvent(pSocket->m_hWSAEvent[1]);
    break;
    }
      if(pSocket->m_eiodConnected == -1)
      break;
    if(netEvents.lNetworkEvents & FD_CONNECT)
    {
    //   theApp.ShowMsg(L"收到网络事件FD_CONNECT");
    iError = WSAGetLastError();
    strErr.Format(L"FD_CONNECT:%d %d %d", iError, netEvents.iErrorCode[FD_CONNECT_BIT], pSocket->m_eiodConnected);
    theApp.ShowMsg(strErr);     if(pSocket->m_eiodConnected == 2)
    {
    ::SendMessage(pSocket->m_hRecEventMsgWnd, pSocket->m_nRecMsgFlag, (WPARAM)WM_FD_CONNECT, (LPARAM)1);
    pSocket->m_eiodConnected = 2;
    break;
    }
    else if(netEvents.iErrorCode[FD_CONNECT_BIT] == 0 && pSocket->m_eiodConnected != -1 
    && (iError == 0 || iError == WSAEWOULDBLOCK || iError == WSAENOTSOCK))
    {
    ::SendMessage(pSocket->m_hRecEventMsgWnd, pSocket->m_nRecMsgFlag, (WPARAM)WM_FD_CONNECT, (LPARAM)1);
    pSocket->m_eiodConnected = 2;
    }
    else
    {
        theApp.ShowMsg(L"发送连接失败的消息");
    pSocket->m_eiodConnected = -1;
    //发送连接失败的消息
    // closesocket(pSocket->m_socket);
    // pSocket->m_socket = INVALID_SOCKET;
    ::SendMessage(pSocket->m_hRecEventMsgWnd, pSocket->m_nRecMsgFlag, (WPARAM)WM_FD_DISCONNECT, (LPARAM)netEvents.iErrorCode[4]);
    }
    break;
    }
    if(netEvents.lNetworkEvents & FD_WRITE)
    {
    /* theApp.ShowMsg(L"收到网络事件FD_WRITE");
    if(pSocket->m_eiodConnected == 1)
    {
    ::SendMessage(pSocket->m_hRecEventMsgWnd, pSocket->m_nRecMsgFlag, (WPARAM)WM_FD_CONNECT, (LPARAM)1);
    pSocket->m_eiodConnected = 2;
    }
    */ break;
    } if(netEvents.lNetworkEvents & FD_READ)
    {
    ZeroMemory(recvBuf,1024);
    recvLen = recv(pSocket->m_socket,recvBuf, sizeof(PDA_HEADER), 0); 
    if (recvLen == SOCKET_ERROR || recvLen == 0)
    {
    // iError = WSAGetLastError();
    //触发与服务器断开事件
    // ::SendMessage(pSocket->m_hRecEventMsgWnd, pSocket->m_nRecMsgFlag, (WPARAM)WM_FD_CLOSE, (LPARAM)iError);
    //关闭客户端socket
    // closesocket(pSocket->m_socket);
    break;
    }
    else
    { //触发数据接收事件
    recvLen = recv(pSocket->m_socket, recvBuf + sizeof(PDA_HEADER), ((PDA_HEADER *)recvBuf)->nLen, 0); 
    ::SendMessage(pSocket->m_hRecEventMsgWnd, pSocket->m_nRecMsgFlag, (WPARAM)WM_FD_READ, (LPARAM)recvBuf);
    }
    }
    if(netEvents.lNetworkEvents & FD_CLOSE)
    {
    iError = WSAGetLastError();
    strErr.Format(L"FD_CLOSE:%d", iError);
        theApp.ShowMsg(strErr);
    ::SendMessage(pSocket->m_hRecEventMsgWnd, pSocket->m_nRecMsgFlag, (WPARAM)WM_FD_CLOSE, (LPARAM)9);
    pSocket->m_eiodConnected = -1;
    //触发连接断开事件
    closesocket(pSocket->m_socket);
    pSocket->m_socket = INVALID_SOCKET;
    //关闭客户端socket
    } break;
    default:
    break;
    }
    }
    return 0;
    }