Может ли несколько select () разрешено в одной клиент-серверной программе TCP - PullRequest
2 голосов
/ 03 мая 2011

Я занимаюсь разработкой клиент-серверной программы на платформе Windows, используя c ++, которая выглядит следующим образом.

1.У меня есть удаленный центр обработки данных (сервер).
2. У меня есть один шлюз (клиент), который будет соединяться с центром обработки данных (tcp).
3. У меня есть приложение с графическим интерфейсомкоторый управляет шлюзом удаленно.

Так что здесь для GUI Gateway есть сервер.

Я сделал следующие вещи

У меня есть два потока слушателя в шлюзе, где в каждомвызывается системный вызов thread select ().

  1. Поток прослушивателя ЦОД - это будет развлекать данные из ЦОД.
  2. Поток слушателя GUI - он будет развлекать данные из GUI.

, когда я запускаю шлюз, автоматически запускается два слушателя и прослушивает соединение и данные как из центра обработки данных, так и из GUI.,

Шлюз соединен с центром обработки данных и также принимает данные.Но когда я запускаю приложение GUI и пытаюсь подключиться, соединение возвращает 0, но оно не вызывает accept в потоке слушателя GUI в шлюзе.

  1. Эта проблема из-за двух системных вызовов select в приложении?
  2. если это так, что является причиной для этого .?

    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);
        itrGatewayCon++;
    }
    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;
     }
    

1 Ответ

2 голосов
/ 03 мая 2011

Вы проверили руководство для выбранной реализации?Потому что select обычно предполагает, что первый параметр будет самым большим fd +1.Смотрите здесь: http://www.manpagez.com/man/2/select/

в основном, select можно использовать более одного раза в приложении, но fd-маски (параметр 2,3,4) должны отличаться - в противном случае обработка ввода будет дублирована.

РЕДАКТИРОВАТЬ:

Возвращаемое значение 0 указывает на тайм-аут, нет активности ни на одном из указанных fds.

hth Марио

...