使用win32项目在少数windows机器上无法建立IPC连接

问题描述

我创建了两个 win32 服务器 C++ 项目,它们都将执行类似的任务,例如侦听来自客户端的 IPC 连接。两者都将侦听不同的端口号,例如 1000 和 2000,我可以连接第一个启动的应用程序,例如 1000 或 2000,但不能同时连接,每隔一个连接请求就会在客户端超时。

下面我添加了我的客户端和服务器代码我有两个端口号不同(1000 和 2000)的服务器应用程序和两个连接到 1000 和 2000 端口服务器应用程序的客户端应用程序。

两个服务器应用程序都将进入侦听模式,但一个只接受连接请求,另一个将在客户端应用程序中引发超时。如果有任何建议,请更新您的意见。

客户代码

      void Initialize()
    {
        WSADATA WSAData;
        WSAStartup(MAKEWORD(2,2),&WSAData);
    }
    
    SOCKET CloseSocket(SOCKET _Socket)
    {
        /*A shutdown() closes SOCK_STREAM sockets gracefully. Both processes can ackNowledge that they are no longer sending. OR disable sends and/or receives on a socket*/
        shutdown(_Socket,SD_BOTH);
        /*The closesocket function closes an existing socket.*/
        closesocket(_Socket);
        return _Socket = INVALID_SOCKET;
    }
    
    SOCKET Connect( SOCKET _Socket,SOCKADDR_IN _Addres )
    {           
        int connectResult   = connect(_Socket,(struct sockaddr *)&_Addres,sizeof(_Addres));       
        if(connectResult == SOCKET_ERROR)
        {
            _Socket = CloseSocket(_Socket);     
        }
        else if(connectResult == ETIMEDOUT)
        {       
            _Socket = CloseSocket(_Socket);
        }   
        return _Socket;
    }
    
    
    SOCKET ClientSocketPipline(SOCKET _Socket)
    {   
        /*Socket types are defined in sys/socket.h. These types--SOCK_STREAM,SOCK_DGRAM,or SOCK_RAW--are supported by AF_INET and AF_UNIX. The following creates a stream socket in the Internet domain:*/
        if ((_Socket = socket(AF_INET,SOCK_STREAM,0)) < 0)
        {           
            return _Socket = CloseSocket(_Socket);      
        }
        
        struct timeval timeout;   
        memset(&timeout,sizeof(timeout));
        timeout.tv_sec  = 2;
        timeout.tv_usec = 0;    
        if (    setsockopt (_Socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout)) < 0 && 
                setsockopt (_Socket,SO_RCVTIMEO,sizeof(timeout)) < 0    )
        {       
            return _Socket = CloseSocket(_Socket);      
        }       
        return _Socket;
    }
    
    void ClientConnectionCall()
    {
        SOCKET ConnectSocket;
        ConnectSocket   = INVALID_SOCKET;   
        ConnectSocket   = ClientSocketPipline(ConnectSocket);   
        SOCKADDR_IN SocketAddres;
                memset(&SocketAddres,sizeof(SocketAddres));       
                /*Convert IPv4 and IPv6 addresses from text to binary form*/
                if(inet_pton(AF_INET,"192.160.1.1",&SocketAddres.sin_addr.s_addr)>0) 
                {           
                    SocketAddres.sin_port       = htons(1000); // and 2000
                    SocketAddres.sin_family     = AF_INET;           
                    ConnectSocket               = Connect(ConnectSocket,SocketAddres);         
                }
    }

int _tmain(int argc,_TCHAR* argv[])
{
    Initialize(); 
    ClientConnectionCall(); 
    return 0;
}

服务器代码监听器(端口号:1000):

SOCKET ServerClass::CloseSocket(SOCKET _Socket)
{
    /*A shutdown() closes SOCK_STREAM sockets gracefully. Both processes can ackNowledge that they are no longer sending. OR disable sends and/or receives on a socket*/
    shutdown(_Socket,SD_BOTH);
    /*The closesocket function closes an existing socket.*/
    closesocket(_Socket);
    return _Socket = INVALID_SOCKET;
}

SOCKET ServerClass::Bind(SOCKET _Socket,SOCKADDR_IN _Address)
{               
    /*bind : Associate a local address with a socket.*/
    if(::bind(_Socket,(struct sockaddr*)&_Address,sizeof(_Address)) == SOCKET_ERROR)
    {       
        _Socket = CloseSocket(_Socket); 
    }   
    return _Socket;
}

SOCKET ServerClass::ServerSocketPipline(SOCKET _Socket,int _Type)
{
    /*Socket types are defined in sys/socket.h. These types--SOCK_STREAM,or SOCK_RAW--are supported by AF_INET and AF_UNIX. The following creates a stream socket in the Internet domain:*/
    if ((_Socket = socket(AF_INET,_Type,0)) < 0)
    {               
        return _Socket = CloseSocket(_Socket);      
    }

    int opt = 1; 
    /* Set socket keep connections alive */
    if (setsockopt(_Socket,SO_REUSEADDR,(char *)&opt,sizeof(opt)) == SOCKET_ERROR)
    {       
        return _Socket = CloseSocket(_Socket);  
    }   
    return _Socket;
}

SOCKET ServerClass::CreateSocket(SOCKET _Socket,int _Port)
{
    _Socket     = INVALID_SOCKET;   
    _Socket     = ServerSocketPipline(_Socket,SOCK_STREAM);

    SOCKADDR_IN SocketAddres;
    memset(&SocketAddres,sizeof(SocketAddres));   

    SocketAddres.sin_addr.s_addr    = htonl(INADDR_ANY);
    SocketAddres.sin_port           = htons(_Port);
    SocketAddres.sin_family         = AF_INET;

    //Associate a local address with a socket.
    _Socket = Bind( _Socket,SocketAddres   );

    /*Establish a socket to listen for incoming connection*/
    if(::listen(_Socket,5) != SOCKET_ERROR)
    {   
        //Socket listen success.
    }
    else
    {                   
        //Socket listen Failed.    
        _Socket = SOCKET_ERROR;
    }   
    return _Socket;
}

DWORD WINAPI ServerClass::SocketListener(LPVOID threadParam)
{
    if(threadParam != NULL)
    {             
            ServerClass *thisClass = (ServerClass *)threadParam;

            SOCKET tempSocket   = INVALID_SOCKET;
            socklen_t addrlen   = sizeof(struct sockaddr_in);
            SOCKADDR_IN SocketAddres;
            memset(&SocketAddres,sizeof(SocketAddres));   

            SocketAddres.sin_addr.s_addr    = htonl(INADDR_ANY);
            SocketAddres.sin_port           = htons(1000);
            SocketAddres.sin_family     = AF_INET;

            if(thisClass->m_BindSock != INVALID_SOCKET)
            {                               
                /*Accept a connection on a socket.*/
                tempSocket = ::accept(  thisClass->m_BindSock,(struct sockaddr*)&SocketAddres,&addrlen);
                if(tempSocket != INVALID_SOCKET)                    
                {                                                       
                    SetEvent(thisClass->m_SocketThreadHandle); 
                }
                else
                {                           
                    tempSocket = thisClass->CloseSocket(tempSocket);  
                    SetEvent(thisClass->m_SocketThreadHandle); 
                }                                       

            }
    }  
    return 0;
}


ServerClass::ServerMainCall(void)
{
     Initialize();
     m_BindSock = CreateSocket(m_BindSock,1000);
     m_SocketThreadHandle = CreateThread(NULL,SocketListener,this,NULL);
       
      WaitForSingleObject(m_SocketThreadHandle,INFINITE);

      int msgBoxID = MessageBox( NULL,L"Connection request received from first client",L"",MB_ICONEXCLAMATION | MB_OK );

                
}

服务器代码监听器(端口号:2000):

SOCKET ServerClass::CloseSocket(SOCKET _Socket)
{
    /*A shutdown() closes SOCK_STREAM sockets gracefully. Both processes can ackNowledge that they are no longer sending. OR disable sends and/or receives on a socket*/
    shutdown(_Socket,sizeof(opt)) == SOCKET_ERROR)
    {       
        return _Socket = CloseSocket(_Socket);  
    }  
    return _Socket;
}

SOCKET ServerClass::CreateSocket(SOCKET _Socket,5) != SOCKET_ERROR)
    {   
        //Socket listen success.
    }
    else
    {                   
        //Socket listen Failed.   
        _Socket = SOCKET_ERROR;
    }   
    return _Socket;
}

DWORD WINAPI ServerClass::SocketListener(LPVOID threadParam)
{
    if(threadParam != NULL)
    {         
           ServerClass *thisClass = (ServerClass *)threadParam;

            SOCKET tempSocket   = INVALID_SOCKET;
            socklen_t addrlen   = sizeof(struct sockaddr_in);
            SOCKADDR_IN SocketAddres;
            memset(&SocketAddres,sizeof(SocketAddres));   

            SocketAddres.sin_addr.s_addr    = htonl(INADDR_ANY);
            SocketAddres.sin_port           = htons(2000);
            SocketAddres.sin_family     = AF_INET;

            if(thisClass->m_BindSock != INVALID_SOCKET)
            {                               
                /*Accept a connection on a socket.*/
                tempSocket = ::accept(  thisClass->m_BindSock,&addrlen);
                if(tempSocket != INVALID_SOCKET)                    
                {                                                       
                    SetEvent(thisClass->m_SocketThreadHandle); 
                }
                else
                {                               
                    tempSocket = thisClass->CloseSocket(tempSocket);    
                    SetEvent(thisClass->m_SocketThreadHandle); 
                }                                       
            }   
    }   
    return 0;
}


ServerClass::ServerMainCall(void)
{
     Initialize();
     m_BindSock = CreateSocket(m_BindSock,2000);  
     m_SocketThreadHandle = CreateThread(NULL,NULL);
   
      WaitForSingleObject(m_SocketThreadHandle,L"Connection request received from second client",MB_ICONEXCLAMATION | MB_OK);

}

解决方法

终于找到问题的答案了。问题是由于服务器机器端的防火墙阻止。禁用它后,一切开始工作,有关更多详细信息,请访问以下链接:

What can be the reasons of connection refused errors?