首页 > 解决方案 > 使用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,0,sizeof(timeout));
        timeout.tv_sec  = 2;
        timeout.tv_usec = 0;    
        if (    setsockopt (_Socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0 && 
                setsockopt (_Socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0    )
        {       
            return _Socket = CloseSocket(_Socket);      
        }       
        return _Socket;
    }
    
    void ClientConnectionCall()
    {
        SOCKET ConnectSocket;
        ConnectSocket   = INVALID_SOCKET;   
        ConnectSocket   = ClientSocketPipline(ConnectSocket);   
        SOCKADDR_IN SocketAddres;
                memset(&SocketAddres,0,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, 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, _Type, 0)) < 0)
    {               
        return _Socket = CloseSocket(_Socket);      
    }

    int opt = 1; 
    /* Set socket keep connections alive */
    if (setsockopt(_Socket,SOL_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,0,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,0,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, 0, SocketListener, this, 0, 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,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, 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, _Type, 0)) < 0)
    {               
        return _Socket = CloseSocket(_Socket);      
    }

    int opt = 1; 
    /* Set socket keep connections alive */
    if (setsockopt(_Socket,SOL_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,0,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,0,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, (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,2000);  
     m_SocketThreadHandle = CreateThread(NULL, 0, SocketListener, this, 0, NULL);
   
      WaitForSingleObject(m_SocketThreadHandle,INFINITE);

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

}

标签: c++winapiipcwinsockwinsock2

解决方案


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

连接被拒绝错误的原因是什么?


推荐阅读