void EPosixClientSocket::eDisconnect() { if ( m_fd >= 0 ) // close socket SocketClose( m_fd); m_fd = -1; // uninitialize Winsock DLL (only for Windows) SocketsDestroy(); eDisconnectBase(); }
EClientSocket::~EClientSocket() { if( m_fd != -2) SocketsDestroy(); }
/** * Same as eConnect() except you may the specify address family here (default is * AF_UNSPEC). * We couldn't just add the new family arg to eConnect because the original one * is pure virtual declared in EClientSocketBase. Thanks C++ design crap ... */ bool EPosixClientSocket::eConnect2( const char *host, unsigned int port, int clientId, int family ) { // already connected? if( m_fd >= 0) { assert(false); // for now we don't allow that return true; } // initialize Winsock DLL (only for Windows) if ( !SocketsInit()) { // Does this set errno? getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), "Initializing Winsock DLL failed."); return false; } // use local machine if no host passed in if ( !( host && *host)) { host = "127.0.0.1"; } // starting to connect to server struct addrinfo *aitop; int s = resolveHost( host, port, family, &aitop ); if( s != 0 ) { SocketsDestroy(); const char *err; #ifdef HAVE_GETADDRINFO err = gai_strerror(s); #else err = "Invalid address, hostname resolving not supported."; #endif getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } int con_errno = 0; for( struct addrinfo *ai = aitop; ai != NULL; ai = ai->ai_next ) { // create socket m_fd = socket(ai->ai_family, ai->ai_socktype, 0); if( m_fd < 0) { con_errno = errno; continue; } /* Set socket O_NONBLOCK. If wanted we could handle errors (portability!) We could even make O_NONBLOCK optional. */ int sn = set_socket_nonblock( m_fd ); assert( sn == 0 ); // try to connect if( timeout_connect( m_fd, ai->ai_addr, ai->ai_addrlen ) < 0 ) { con_errno = errno; SocketClose(m_fd); m_fd = -1; continue; } /* successfully connected */ break; } freeaddrinfo(aitop); /* connection failed, tell the error which happened in our last try */ if( m_fd < 0 ) { const char *err = strerror(con_errno); SocketsDestroy(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } // set client id setClientId( clientId); errno = 0; onConnectBase(); if( !isOutBufferEmpty() ) { /* For now we consider it as error if it's not possible to send an integer string within a single tcp packet. Here we don't know weather ::send() really failed or not. If so then we hopefully still have it's errno set.*/ const char *err = (errno != 0) ? strerror(errno) : "Sending client id failed."; eDisconnect(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } if( wait_socket( m_fd, WAIT_READ ) <= 0 ) { const char *err = (errno != 0) ? strerror(errno) : strerror(ENODATA); eDisconnect(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } while( !isConnected() ) { assert( isSocketOK() ); // need to be handled if send() would destroy it if ( !checkMessagesConnect()) { const char *err = (errno != 0) ? strerror(errno) : "The remote host closed the connection."; eDisconnect(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), err ); return false; } } // successfully connected return true; }
bool EPosixClientSocket::eConnect( const char *host, unsigned int port, int clientId) { // reset errno errno = 0; // already connected? if( m_fd >= 0) { errno = EISCONN; getWrapper()->error( NO_VALID_ID, ALREADY_CONNECTED.code(), ALREADY_CONNECTED.msg()); return false; } // initialize Winsock DLL (only for Windows) if ( !SocketsInit()) { return false; } // create socket m_fd = socket(AF_INET, SOCK_STREAM, 0); // cannot create socket if( m_fd < 0) { // uninitialize Winsock DLL (only for Windows) SocketsDestroy(); getWrapper()->error( NO_VALID_ID, FAIL_CREATE_SOCK.code(), FAIL_CREATE_SOCK.msg()); return false; } // use local machine if no host passed in if ( !( host && *host)) { host = "127.0.0.1"; } // starting to connect to server struct sockaddr_in sa; memset( &sa, 0, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons( port); sa.sin_addr.s_addr = inet_addr( host); // try to connect if( (connect( m_fd, (struct sockaddr *) &sa, sizeof( sa))) < 0) { // error connecting // uninitialize Winsock DLL (only for Windows) SocketsDestroy(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg()); return false; } // set client id setClientId( clientId); onConnectBase(); while( isSocketOK() && !isConnected()) { if ( !checkMessages()) { // uninitialize Winsock DLL (only for Windows) SocketsDestroy(); getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg()); return false; } } // successfully connected return true; }