我在atl的那个类的install函数里面初始化socket,用的是SOCKET,没用CSocket,一切正常,
然后启动侦听线程,把侦听SOCKET作为参数传过去,afxbeginthead(listenProc,listenSocket);
线程函数如下:
UNIT listenProc(LPVOID lp)
{
    SOCKET listenSocket=*(SOCKET *)LP;
    SOCKET chatSocket=accept(socket,NULL,NULL);//调试到这里就出现一个对话框,thread 返回值为0退出。
}如果我把不用线程的话,就没有问题,可以阻塞侦听,但是这样程序就不对了,因为阻塞在那里,服务就没法启动了,除非有客户端连接。。
为什么放在线程中就不行了呢?高手来帮帮忙把

解决方案 »

  1. install()里面执行了afxbeginthead之后是不是有其他的操作,使得listenSocket关闭了呀?
    最好帖出相关部分代码,否则没有办法判断呀.
      

  2. 没有关闭阿,代码如下:inline BOOL CServiceModule::Install()
    {
    if (!AfxSocketInit())
    {
    // AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
    return  0;
    } SOCKET m_hListenSocket=0; in_addr m_HostAddr;
    SOCKADDR_IN m_addr;
    int m_nPort; /////////////////////////
    //取得本机ip
    char szHostName[128];
    if( gethostname(szHostName, 128) == 0 )
    {
    // Get host adresses
    //m_strHostName = szHostName;
    hostent * pHost;
    pHost = gethostbyname(szHostName); 
    in_addr *addr;
    for( int i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ ) 
    {

    //char *pAddr=inet_ntoa (*(struct in_addr *)pHost->h_addr_list[i]);
                addr = (struct in_addr *)pHost->h_addr_list[i];
              //m_ctrlHostIP.SetAddress(addr->S_un.S_un_b.s_b1,addr->S_un.S_un_b.s_b2,addr->S_un.S_un_b.s_b3,addr->S_un.S_un_b.s_b4);
     
    }
    m_HostAddr = *addr;
             m_nPort= 4000; }
    //
    if(m_hListenSocket)
    {
    closesocket(m_hListenSocket);
    m_hListenSocket=NULL;
    return 0 ;
    }
    m_hListenSocket = socket(AF_INET,SOCK_STREAM,0);
    // DWORD cmd = true;
    // ioctlsocket(m_hListenSocket,FIONBIO,&cmd); m_addr.sin_family = AF_INET;
    m_addr.sin_addr = m_HostAddr; 
    // m_addr.sin_addr.S_un.S_addr = INADDR_ANY;
    m_addr.sin_port = htons(m_nPort);

    int ret = bind(m_hListenSocket,(sockaddr*)&m_addr,sizeof(m_addr));
    if(ret==SOCKET_ERROR)
    {
    printf("Bind Error!");
    return 0 ;
    }
     
     if((ret = listen(m_hListenSocket,2))==SOCKET_ERROR)
    {
    printf("Listen Error!");
    return 0 ;
    } fd_set fdread;
    FD_ZERO(&fdread);
    FD_SET(m_hListenSocket,&fdread);
    timeval timeout = {5,5};
    // select(0,&fdread,NULL,NULL,&timeout);
    //int ret=0; //SOCKET m_hListenSocket =*(SOCKET*)pParam;
    /* SOCKET m_hCommuSocket;
    if((m_hCommuSocket = accept(m_hListenSocket,NULL,NULL))==SOCKET_ERROR)
    {
    printf("Accept Error!");
    return 1;
    } Add("连接成功!"); char buff[256]; ret = recv(m_hCommuSocket, buff, 256, 0);
    if(ret == 0){
    TRACE("Recv data error: %d\n", WSAGetLastError());
    printf("recive error!");
    return -1;
    }
    buff[ret] = '\0';
    printf(buff);*/ AfxBeginThread(ListenProc,&m_hListenSocket);
        if (IsInstalled())
            return TRUE;    SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
        if (hSCM == NULL)
        {
            MessageBox(NULL, _T("Couldn't open service manager"), m_szServiceName, MB_OK);
            return FALSE;
        }    // Get the executable file path
        TCHAR szFilePath[_MAX_PATH];
        ::GetModuleFileName(NULL, szFilePath, _MAX_PATH);    SC_HANDLE hService = ::CreateService(
            hSCM, m_szServiceName, m_szServiceName,
            SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
            SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,
            szFilePath, NULL, NULL, _T("RPCSS\0"), NULL, NULL);    if (hService == NULL)
        {
            ::CloseServiceHandle(hSCM);
            MessageBox(NULL, _T("Couldn't create service"), m_szServiceName, MB_OK);
            return FALSE;
        }    ::CloseServiceHandle(hService);
        ::CloseServiceHandle(hSCM);
        return TRUE;
    }UINT ListenProc( LPVOID pParam )
    {
    int ret=0; SOCKET m_hListenSocket =*(SOCKET*)pParam;
    SOCKET m_hCommuSocket;
    if((m_hCommuSocket = accept(m_hListenSocket,NULL,NULL))==SOCKET_ERROR)
    {
    printf("Accept Error!");
    return 1;
    } printf("连接成功!"); char buff[256]; ret = recv(m_hCommuSocket, buff, 256, 0);
    if(ret == 0){
    TRACE("Recv data error: %d\n", WSAGetLastError());
    printf("recive error!");
    return -1;
    }
    buff[ret] = '\0';
    printf(buff); return 0;
    }
      

  3. 我觉得不应该放到Install函数里,因为这只是个安装服务的函数,安装完后程序应该就退出了.应该放在服务启动的地方.
    比如   _tWinMain里.
      

  4. 说得对,但_tWinMain好像也不行,放在run里面可以
    谢谢你的关注和重大提示!
      

类似问题 »