C++ 套接字连接问题

Posted

技术标签:

【中文标题】C++ 套接字连接问题【英文标题】:C++ Socket Connect Issue 【发布时间】:2016-02-18 12:42:20 【问题描述】:

我有一个套接字连接功能,问题是如果客户端在服务器之前启动,连接显示为已连接,但由于某种原因返回失败。我不确定失败在哪里,非常感谢任何帮助:

函数是:

bool IPV4Socket::Connect( std::string hostname
                    , unsigned short remotePort
                    , TimeoutValue *timeout )

    AddrInfo getResults;
    AddrInfo getaddrinfoHints;
    int connReturn = 0;
    SockAddr_In *addrData;
    bool connectSuccess = false;
    std::string service = std::to_string( remotePort );

    getaddrinfoHints.ai_family = AddressFamily_inet;
    getaddrinfoHints.ai_socktype = SockType_stream;

    if ( m_socketAdaptor->getaddrinfo( hostname
                                 , service
                                 , &getaddrinfoHints
                                 , &getResults ) != 0 )
    
        return false;
    

    addrData = (SockAddr_In *)&( *getResults.ai_addr.begin() );

    connReturn = m_socketAdaptor->connect( m_socket
                                         , (const Sockaddr *)addrData
                                         , (int)getResults.ai_addrlen );

    if ( connReturn == SocketError)
    
        int m_lastErrorCode = m_socketAdaptor->GetLastError();

        //  Connection error : FATAL 
        if ( ( m_lastErrorCode != SockErr_EWOULDBLOCK) &&
             ( m_lastErrorCode != SockErr_EALREADY ) )
        
            connectSuccess = false;
        
        else
        
           SocketSet writeFDS;
           SocketSet exceptFDS;
           int selectReturn = 0;

           //  Clear all the socket FDS structures
           SocketSet_ZERO( &writeFDS );
           SocketSet_ZERO( &exceptFDS );

           //  Put the socket into the FDS structures
           SocketSet_SET( m_socket, &writeFDS );
           SocketSet_SET( m_socket, &exceptFDS );

           selectReturn = m_socketAdaptor->select( -1
                                                 , NULL
                                              , &writeFDS
                                              , &exceptFDS
                                              , timeout );

           if ( selectReturn == SocketError )
           
               //  Any errors are bad
               connectSuccess = false;
           
           else if ( selectReturn > 0 )
           
                //  Check for error (exception) first
                if ( m_socketAdaptor->SocketSet_ISSET( m_socket, &exceptFDS ) )
                
                    connectSuccess = false;
                
                else if ( m_socketAdaptor->SocketSet_ISSET( m_socket, &writeFDS ) )
                
                    //   Select returned 'writable', we're connected!
                    connectSuccess = true;
                    m_isConnected = true;
                
            
        
    
    else
    
        connectSuccess = true;
        m_isConnected = true;
    

    return connectSuccess;

我不确定我是否遗漏了要点,或者我是否过于复杂了函数。

哎呀 :)

注意事项: * 顺便说一下,m_socketAdaptor-> 函数只是包装器。 * 如果你先启动服务器再启动客户端,它就可以工作...

【问题讨论】:

客户端在启动服务器之前运行时netstat显示什么? @UmamaheshP 使用 'netstat -a -p tcp 10' 我得到:TCP 127.0.0.1:51074 WINDEVSRV:3490 SYN_SENT 这是预期的行为。发送 syn 是 TCP 握手的第一步。如果服务器没有监听该端口,则连接将失败。客户端需要重新尝试连接。 @UmamaheshP 在服务器端,我收到客户端已连接的通知,连接返回失败(false)并已连接(10056)。这让我认为 connect 是错误的? 如果没有程序在侦听端口上侦听,则没有客户端能够建立连接。如果客户端无法连接,那么这是预期的行为。 netstat 是否显示连接到服务器的客户端?除非您在同一台机器上同时运行客户端和服务器,否则您需要在服务器端和客户端运行 netstat。 【参考方案1】:

您不能重新连接已经连接失败的套接字。您必须关闭它并创建一个新套接字。因此,这应该在 connect 方法中完成,而不是现在在哪里完成。

【讨论】:

以上是关于C++ 套接字连接问题的主要内容,如果未能解决你的问题,请参考以下文章

线程中的套接字接受所有端口连接? C++

具有多个连接的 C++ 服务器套接字

c++ 服务器在客户端终止连接进程后不关闭 TCP 套接字连接

服务器套接字只能连接几次(Winsock C++)

多连接客户端套接字应用程序 C++

在 C++ 中的 UDP 套接字编程中获取“传输端点未连接”