The C++ API in IB may be structures differently (have not looked at your c++ code in detail) but the IsConnected method in c# is indeed utterly useless. One has to implement something on his one.
Further how IB's API disconnects is a disgrace. Invoking disconnect basically throws errors because the socket is disconnected but the while loop that polls the socket is not exited.
There are truly some very strange things the IB coders either don't understand, or did not have time to implement, or are incapable of implementing.
No biggies for a capable coder to circumvent but true annoyances.
Further how IB's API disconnects is a disgrace. Invoking disconnect basically throws errors because the socket is disconnected but the while loop that polls the socket is not exited.
There are truly some very strange things the IB coders either don't understand, or did not have time to implement, or are incapable of implementing.
No biggies for a capable coder to circumvent but true annoyances.
I had a similar problem and combed through the code a little while back.
An isConnected() method exists in the test files, and is implemented as follows. I'm running C++ v9.72.14, and it does pretty much what you're looking for. You don't say what version (or what language) you're using, but this example may help you.
Main.cpp: note how the while(client.isConnected) statement is called win the endless for (;loop. This is basically the keep-alive previously discussed.
Code:for (;;) { ++attempt; printf( "Attempt %u of %u\n", attempt, MAX_ATTEMPTS); TestCppClient client(clientId, category, ticker, shares, bid, ask, stop); if(connectOptions) { client.setConnectOptions(connectOptions); } printf( "client.connect result: %d\n", client.connect(host, port, clientId)); while( client.isConnected()) { client.processMessages(); } if( attempt >= MAX_ATTEMPTS) { break;} printf( "Sleeping %u seconds before next attempt\n", SLEEP_TIME); sleep( SLEEP_TIME); } printf ( "End of C++ Socket Client Test\n");
After the class TestCppClient is instantiated, the isConnected() method is available on the interface. Here is the definition:
Code:bool TestCppClient::isConnected() const { return m_pClient->isConnected(); }
So you should be able to use this provided method. Just instantiate the class, and call the method.
If you really want (or need) to get in deeper, there is more:
From TestCppClient.h:
m_pClient is pointer to an instance of EClientSocket.
Code:private: //! [socket_declare] EClientSocket * const m_pClient;
EClientSocket.h
EClientSocket inherits from both EClient and EClientMsgSink:
Code:class TWSAPIDLLEXP EClientSocket : public EClient, public EClientMsgSink {
EClient: There's a few public methods here that may help.
Code:EClient::ConnState EClient::connState() const { return m_connState; } bool EClient::isConnected() const { return m_connState == CS_CONNECTED; } bool EClient::isConnecting() const { return m_connState == CS_CONNECTING; }
Note that ConnState is an enum. Perhaps the connState() method may be of use? Not that ConnState is an enum:
Code:enum ConnState { CS_DISCONNECTED, CS_CONNECTING, CS_CONNECTED, CS_REDIRECT };
EClient.cpp
The actual connection request is in the following method. It is protected, so note that you're getting pretty deep in here.
Code:int EClient::sendConnectRequest() { m_connState = CS_CONNECTING; int rval; // send client version std::stringstream msg; if( m_useV100Plus) { msg.write( API_SIGN, sizeof(API_SIGN)); prepareBufferImpl( msg); if( MIN_CLIENT_VER < MAX_CLIENT_VER) { msg << 'v' << MIN_CLIENT_VER << ".." << MAX_CLIENT_VER; } else { msg << 'v' << MIN_CLIENT_VER; } if( !m_connectOptions.empty()) { msg << ' ' << m_connectOptions; } rval = closeAndSend( msg.str(), sizeof(API_SIGN)); } else { ENCODE_FIELD( CLIENT_VERSION); rval = bufferedSend( msg.str()); } m_connState = rval > 0 ? CS_CONNECTED : CS_DISCONNECTED; return rval; }
You could dig into the closeAndSend() method from here...
