Visualizzazione dei risultati da 1 a 4 su 4
  1. #1
    Utente di HTML.it L'avatar di mr.and
    Registrato dal
    Dec 2008
    Messaggi
    51

    [C] problema select winsock

    Salve,
    sto implementando un server che rimane in attesa di connessioni da parte di client, ricevute le quali, lancia un nuovo thread a cui passa la connessione ottenuta.
    Per gestire al meglio le operazioni di terminazione di tale server, ho utilizzato una select che gestisce il timeout per la accept sul socket d'ascolto.
    Però da quando ho aggiunto la select il mio server non funziona più a dovere: i thread(server dedicati) terminano improvvisamente la loro connessione!

    Posto il codice del server principale:


    /* main */
    codice:
    int main(int argc, char* argv []){
    
    
    /* AMBIENTE WINDOWS  */ 
    
       HANDLE ListaServer[MAX_SERV];
       HANDLE Console;
       DWORD ConsoleId;
       DWORD ServID[MAX_SERV];
       SOCKADDR_IN Client_addr;
       SOCKET listenSocket;
       SOCKET connessione;
       int id_serv,sin_size,i,n;
       LONG cnt;
       LONG volatile flag;
       LONG volatile client[MAX_SERV];
       serv_arg* param;
       fd_set rset;
       struct timeval tv;
       u_long iMode;
    
    
    /*inizializzazione libreria Socket*/
    
       WORD wVersionRequested = MAKEWORD(2,2);
       WSADATA wsaData;
       int wsastartup = WSAStartup(wVersionRequested, &wsaData);
       if (wsastartup != NO_ERROR) printf("Errore WSAStartup()\n");
       
       id_serv=0;
       for(i=0;i<MAX_SERV;i++) client[i]=0;
    
    /* Creazione Thread che rimane in attesa del segnale di terminazione dell'applicazione */ 
    
       Console=(HANDLE)_beginthreadex(NULL,0,(LPTHREAD_START_ROUTINE)Listener,&flag,0,&ConsoleId);
    
    /*Inizializzazione connessione server*/
    
       listenSocket=ConnessioneServer("127.0.0.1",N_PORT,listenSocket);
       if(listenSocket==INVALID_SOCKET){
                                        printf("Errore ConnessioneServer\n");
                                        return -1;
       }
       
       iMode=1;
    
       ioctlsocket(listenSocket, FIONBIO, &iMode);
    
       flag=1;
    
       printf("Mainserver in attesa di client..\n");
    
       while(flag){
    
                FD_ZERO(&rset);
                FD_SET(listenSocket, &rset);
                tv.tv_sec = 10;
                tv.tv_usec = 0;
                if( (n = select(listenSocket + 1, &rset, NULL, NULL, &tv)) < 0 ){
                                                                                printf("Errore Select:%d\n",WSAGetLastError());
                                                                                return -1;
                }
                if(n>0){
                           connessione = accept(listenSocket, (struct sockaddr*)&Client_addr, &sin_size);
                           if(connessione<=0) printf("Errore Accept:%d\n",WSAGetLastError());
    
    	               printf("Accettata Connessione con Client: %s su socket %d\n", inet_ntoa(Client_addr.sin_addr),connessione);
    
                           param=malloc(sizeof(serv_arg));
    
                           for(i=0;i<MAX_SERV;i++) { 
                                                    if(client[i]==0){ 
                                                                      InterlockedIncrement(&(client[i]));
                                                                      break; 
                                                    }
                           }
    
                           (*param).nserv=&(client[i]);
                           (*param).idServ=i;
                           (*param).conn=connessione;
                           (*param).clientAddr.sin_family = AF_INET;
                           (*param).clientAddr.sin_addr.s_addr=Client_addr.sin_addr.s_addr;
                           (*param).clientAddr.sin_port=Client_addr.sin_port;
    
                           ListaServer[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)server,param,0,&ServID[i]);
    
    	    }
       }
    /*rimane in attesa che tutti i server dedicati terminino */
       while(1){
         
         cnt=0;
    
         for(i=0;i<MAX_SERV;i++) cnt+=client[i];
         
         if(cnt==0) break;
         
         else Sleep(10000);
         
       }
    
    /*quindi termina */
    
       shutdown(listenSocket,2);
       close(listenSocket);
    
       WSACleanup();
    
       return 0;
    
    }
    ho aggiunto la temporizzazione mediante select poichè il server avvia all'inizio un thread in ascolto sulla console, il quale pone flag=0 quando viene scritto quit sulla console.
    Senza tale temporizzazione il server sarebbe rimasto comunque in attesa di un ultima richiesta di connessione sulla accept. Mentre in questo modo sen entro il tempo stabilito non giungono nuove richieste di connessione il server può uscire tranquillamente dal ciclo while e condurre le operazioni di terminazione.

    Perchè questo influisce sul comportamento della connessione mantenuta dal server dedicato(il thread che fa riferimento alla funzione server)?

  2. #2
    Utente di HTML.it L'avatar di Ed_Bunker
    Registrato dal
    Jul 2003
    Messaggi
    1,119
    Dettaglia meglio cosa intendi per "improvvisamente".
    Avviene non appena avviati o successivamente ?
    Hai controllato l'exit code dei thread ?

  3. #3
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,565
    Un tizio aveva un problema molto simile.
    Gli suggerii di cambiare begintrheadex con CreateThread e pare funzionare.
    "Se proprio devono piratare, almeno piratino il nostro." (Bill Gates)

    "Non è possibile che 2 istituzioni statali mi mettano esami nello stesso giorno." (XWolverineX)

    http://xvincentx.netsons.org/programBlog

  4. #4
    Utente di HTML.it L'avatar di mr.and
    Registrato dal
    Dec 2008
    Messaggi
    51
    Allora, ho provato a sostituire la _beginthreadex ma niente (anche perchè non era quello il thread interessato ma l'altro, quello che fa riferimento alla routine server).
    Il Thread in questione dovrebbe scambiarsi una serie di messaggi con il client grazie ad un ciclo while improntato su una recv, ma ciò non avveniva...così ragionando sono arrivato alla soluzione: anche la connessione passata al thread era non-bloccante(anche se io ho settato a non bloccante solo quella del server principale,evidentemente la accept ha reso anche il nuovo socket non bloccante,o qualcosa del genere).

    E con questa nuova scoperta ho risolto!...(almeno questo problema....)

    Grazie a tutti!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.