Can multiple select () is allowed in a single tcp client server program
I am developing client server program in windows platform using c++ which is as follows.
1.I have remote data center(server).
2. I have one gateway(client) which will connect with the data center(tcp). 3. I have a gui application which manages the gateway remotely.So here for GUI Gateway is Server.
I did the following things
I have two listener thread in gateway where in each thread select() system call is called.
- Data center Listener Thread- this will entertain the data from the Data center.
- GUI listener thread - this will entertain the data from the GUI.
when i start the gateway two listener automatically starts and listen for the connection and data from both data center and GUI.
Gateway connected with the data center and receives the data as well. BUt when i start the gui application and tries to connect the connect returns 0 but it doesnot call accept in the GUI listener thread in gateway.
- Is this problem due to two select system call in the application?
if it is so what is the reasin for this.?
void* CConnectionMgr::ListnerThreadDataCenter(void* args) { CGatewayInstanceManager* pGatewayInstance = (CGatewayInstanceManager*)args; fd_set fdRead; fd_set fdExcept; int nSelectRetVal = 0; timeval tv; tv.tv_sec = 2; tv.tv_usec = 0; while(true) { FD_ZERO(&fdRead); FD_ZERO(&fdExcept); GatewayConnection::iterator itrGatewayCon; GatewayConnection mapGatewayConn = pGatewayInstance->GetConnectionMgr()->GetGatewayConnection(); itrGatewayCon = mapGatewayConn.begin(); while (itrGatewayCon != mapGatewayConn.end()) { FD_SET (itrGatewayCon->second,&fdRead); FD_SET (itrGatewayCon->second,&fdExcept); itrGa开发者_如何学运维tewayCon++; } nSelectRetVal = select(NULL,&fdRead,NULL,&fdExcept,&tv); // demultiplexing the socket for in coming message if (nSelectRetVal>0) { for ( itrGatewayCon = mapGatewayConn.begin();itrGatewayCon!= mapGatewayConn.end();itrGatewayCon++) { //Reading packet from the socket unsigned char* pPacket = pGatewayInstance->GetConnectionMgr()->ReadPacketDataFromSocket(itrGatewayCon->second); CProtocolMgr objProtocol; CMessage* pMessage = objProtocol.ParseMsg(pPacket); pGatewayInstance->HandleRequest(pMessage); } } DWORD dwWaitResult; dwWaitResult = WaitForSingleObject(ghListenerThreadDataCenterShutdownEvent,WAIT_TIME); if (WAIT_OBJECT_0 == dwWaitResult) break; } return 0; } void* CConnectionMgr::ListnerThreadUI(void* args) { CGatewayInstanceManager* pGatewayInstance = (CGatewayInstanceManager*)args; fd_set fdRead; fd_set fdExcept; int nSelectRetVal = 0; timeval tv; tv.tv_sec = 2; tv.tv_usec = 0; while(true) { FD_ZERO(&fdRead); FD_ZERO(&fdExcept); if (pGatewayInstance->GetConnectionMgr()->GetServerSocket()!=-1 ) { FD_SET (pGatewayInstance->GetConnectionMgr()->GetServerSocket(),&fdRead); FD_SET (pGatewayInstance->GetConnectionMgr()->GetServerSocket(),&fdExcept); } UIConnection::iterator itrUIConnection; UIConnection listUIConnection = pGatewayInstance->GetConnectionMgr()->GetUIConnection(); for(itrUIConnection = listUIConnection.begin();itrUIConnection != listUIConnection.end();itrUIConnection++) { if ( *itrUIConnection != -1) { FD_SET (*itrUIConnection,&fdRead); FD_SET (*itrUIConnection,&fdExcept); } } // demultiplexing the socket for in coming message nSelectRetVal = select(NULL,&fdRead,NULL,&fdExcept,&tv); if(nSelectRetVal>0) { if (FD_ISSET(pGatewayInstance->GetConnectionMgr()->GetServerSocket(),&fdRead)) { // accepting and new client and updating the UIConnection List int nAcceptRetVal = 0; nAcceptRetVal = pGatewayInstance->GetConnectionMgr()->ManageConnection(pGatewayInstance->GetConnectionMgr()); continue; } if (FD_ISSET(pGatewayInstance->GetConnectionMgr()->GetServerSocket(),&fdExcept)) { } for( itrUIConnection = listUIConnection.begin();itrUIConnection != listUIConnection.end();itrUIConnection++) { if (FD_ISSET(*itrUIConnection,&fdRead)) { //Reading packet from the socket //string strPacket = pGatewayInstance->GetConnectionMgr()->ReadPacketDataFromSocket(*itrUIConnection); //pGatewayInstance->HandleRequest(); } } } DWORD dwWaitResult; dwWaitResult = WaitForSingleObject(ghListenerThreadUIShutDownEvent,WAIT_TIME); if (WAIT_OBJECT_0 == dwWaitResult) break; } return 0; } int CConnectionMgr::ManageConnection(CConnectionMgr* pConMgr) { sockaddr_in addrConnectedPeer; int nAddrLen =sizeof(addrConnectedPeer) ; int nAcceptRetVal = accept(pConMgr->GetServerSocket(),(sockaddr*)&addrConnectedPeer,&nAddrLen); if (nAcceptRetVal>0) { pConMgr->AddUIConnection(nAcceptRetVal); } return 0; }
did you check the manual for your select implementation? Because select usually expectes the first param to be the highest fd +1. See here: http://www.manpagez.com/man/2/select/
basically, select can be used more than once in an app, but the fd-masks (param 2,3,4) should be different - otherwise processing of input will be duplicated.
EDIT:
A return value of 0 indicates a timeout, no activity on any of the specified fds.
hth Mario
精彩评论