Ejemplo n.º 1
0
bool EClientSocket::eConnect( const char *host, UINT port, int clientId, bool extraAuth)
{
	// already connected?
	if( isConnected()) {
		getWrapper()->error( NO_VALID_ID, ALREADY_CONNECTED.code(), ALREADY_CONNECTED.msg());
		return false;
	}

	// init sockets
	AfxSocketInit();

	// close open connection if there was one
	eDisconnect();

	// create socket
	m_pSocket.reset(new MySocket(this));
	if( !m_pSocket->Create()) {
		eDisconnect();
		getWrapper()->winError( "Failed to create socket", GetLastError() );
		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";
	}

	// connect to server
	if( !m_pSocket->Connect(host, port)) {
		int lastError = GetLastError();
		if( lastError != WSAEWOULDBLOCK && !handleSocketError(GetLastError())) {
			return false;
		}
	}

	setClientId( clientId);
	setExtraAuth( extraAuth);

	{
		// Wait till we are fully connected (or for an error)
		CWinThread* pThread = AfxGetThread();
		while( m_pSocket.get() && !isConnected()) {
			if (!pThread->PumpMessage())
				return false;
		}
	}
	return true;
}
Ejemplo n.º 2
0
bool EClientSocket::handleSocketError()
{
	// no error
	if( errno == 0)
		return true;

	// Socket is already connected
	if( errno == EISCONN) {
		return true;
	}

	if( errno == EWOULDBLOCK)
		return false;

	if( errno == ECONNREFUSED) {
		getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
	}
	else {
		getWrapper()->error( NO_VALID_ID, SOCKET_EXCEPTION.code(),
			SOCKET_EXCEPTION.msg() + strerror(errno));
	}
	// reset errno
	errno = 0;
	eDisconnect();
	return false;
}
Ejemplo n.º 3
0
void EClientSocket::onClose( int i)
{
	// this function is called when the TWS terminates the connection

	eDisconnect();
	getWrapper()->connectionClosed();
}
Ejemplo n.º 4
0
void EClientSocket::onClose()
{
	if( !handleSocketError())
		return;

	eDisconnect();
	getWrapper()->connectionClosed();
}
Ejemplo n.º 5
0
void EClientSocket::serverVersion(int version, const char *time) {
    m_serverVersion = version;
    m_TwsTime = time;

    if( usingV100Plus() ? (m_serverVersion < MIN_CLIENT_VER || m_serverVersion > MAX_CLIENT_VER) : m_serverVersion < MIN_SERVER_VER_SUPPORTED ) {
        getWrapper()->error( NO_VALID_ID, UNSUPPORTED_VERSION.code(), UNSUPPORTED_VERSION.msg());
        eDisconnect();
    }
}
Ejemplo n.º 6
0
void EPosixClientSocket::onReceive()
{
	if( !checkMessages() ) {
		const char * err = (errno != 0) ? strerror(errno)
			: "The remote host closed the connection.";
		getWrapper()->error( NO_VALID_ID, SOCKET_EXCEPTION.code(), err );
		eDisconnect();
		getWrapper()->connectionClosed();
	}
}
Ejemplo n.º 7
0
void EClientSocket::redirect(const char *host, int port) {
	// handle redirect
	if( (m_hostNorm != this->host() || port != this->port())) {
        if (!m_allowRedirect) {
            getWrapper()->error(NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());

            return;
        }

        eDisconnect();
		eConnectImpl( clientId(), extraAuth(), 0);
	}
}
Ejemplo n.º 8
0
int EPosixClientSocket::send(const char* buf, size_t sz)
{
	assert( sz > 0 );

	int nResult = ::send( m_fd, buf, sz, 0);

	if( nResult == -1 ) {
		if( isConnected() ) {
			const char *err = strerror(errno);
			getWrapper()->error( NO_VALID_ID, SOCKET_EXCEPTION.code(), err );
			eDisconnect();
			getWrapper()->connectionClosed();
		} else {
			/* will be handled within eConnect() ... */
		}
	}

	return nResult;
}
Ejemplo n.º 9
0
///////////////////////////////////////////////////////////
// helper
bool EClientSocket::handleSocketError( int lastError)
{
	if( lastError == ERROR_SUCCESS)
		return true;

	if( lastError == WSAEWOULDBLOCK)
		return false;

	if( lastError == WSAECONNREFUSED) {
		getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
	}
	else {
		char lastErrorStr[512];
		FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, lastError, 0,
			lastErrorStr, sizeof(lastErrorStr), NULL);
		getWrapper()->error( NO_VALID_ID, SOCKET_EXCEPTION.code(),
			SOCKET_EXCEPTION.msg() + lastErrorStr);
	}
	eDisconnect();
	return false;
}
Ejemplo n.º 10
0
EClientSocket::~EClientSocket()
{
	eDisconnect();
}
Ejemplo n.º 11
0
/**
 * 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;
}
Ejemplo n.º 12
0
bool EClientSocket::eConnectImpl(int clientId, bool extraAuth, ConnState* stateOutPt)
{
	// resolve host
	struct hostent* hostEnt = gethostbyname( host().c_str());
	if ( !hostEnt) {
		getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
		return false;
	}

	// create socket
	m_fd = socket(AF_INET, SOCK_STREAM, 0);

	// cannot create socket
	if( m_fd < 0) {
		getWrapper()->error( NO_VALID_ID, FAIL_CREATE_SOCK.code(), FAIL_CREATE_SOCK.msg());
		return false;
	}

	// 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 = ((in_addr*)hostEnt->h_addr)->s_addr;

	// try to connect
	if( (connect( m_fd, (struct sockaddr *) &sa, sizeof( sa))) < 0) {
		// error connecting
		SocketClose( m_fd);
		m_fd = -1;
		getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
		return false;
	}

    getTransport()->fd(m_fd);

	// set client id
	setClientId( clientId);
	setExtraAuth( extraAuth);

    int res = sendConnectRequest();

    if (res < 0 && !handleSocketError())
        return false;

	if( !isConnected()) {
		if( connState() != CS_DISCONNECTED) {
			assert( connState() == CS_REDIRECT);
			if( stateOutPt) {
				*stateOutPt = connState();
			}
			eDisconnect();
		}
		return false;
	}

	// set socket to non-blocking state
	if ( !SetSocketNonBlocking(m_fd)) {
	// error setting socket to non-blocking
		eDisconnect();
		getWrapper()->error( NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg());
		return false;
	}

	assert( connState() == CS_CONNECTED);
	if( stateOutPt) {
		*stateOutPt = connState();
	}
            
    if (!m_asyncEConnect) {
        EReader reader(this, m_pSignal);

        while (m_pSignal && !m_serverVersion && isSocketOK()) {
            reader.checkClient();
            m_pSignal->waitForSignal();
            reader.processMsgs();
        }
    }

	// successfully connected
	return isSocketOK();
}