Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it L'avatar di gaten
    Registrato dal
    Jul 2007
    Messaggi
    1,269

    [C] Socket - Problema con accept

    Ragazzi stò creando una piccola applicazione client server, solo che ho un problema.
    Creo un canale di comunicazione tra client e server e all'inizio va benissimo dopodichè io ho una cosa del tipo:

    codice:
    for(;;)
    {
         accept(socketdescriptor,NULL, NULL);
    }
    in server.c

    e una cosa del tipo:

    codice:
    for(;;)
    {
        write(socketdescriptor, "messaggio", ..);
    }
    La prima volta, funziona benissimo appena tenta di fare la seconda iterazione il for che è all'interno del server.c, la accept restituisce sempre -1, come mai ?? Premetto che ho settato il socket come NON BLOCCANTE tramite una istruzione del tipo:

    codice:
    fcntl(Socket, F_SETFL, O_NONBLOCK);
    Qualcuno può aiutarmi?

    Grazie anticipatamente
    Con i sogni possiamo conoscere il futuro...

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Non ho capito quel for della accept ... c'è solo quel codice ? E quando ottieni il nuovo socket ? Come esci dal ciclo?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it L'avatar di gaten
    Registrato dal
    Jul 2007
    Messaggi
    1,269
    Oregon era per far capire che la accept è all'interno di un loop, il nuovo socket lo ricavo così:

    codice:
    ...
    socketdescriptor=createsocket(porta);
    for (; ;)
    {
    ..
    
    nuovosocket = accept(sokdescriptor, NULL, NULL);
    ..
    }
    Con i sogni possiamo conoscere il futuro...

  4. #4
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Beh .. non devi dare per scontato nulla ... in un forum chi ti legge non "immagina" che ci sia un certo codice ma legge esattamente quello che viene mostrato ...

    Dato che rilevi un comportamento particolare durante il ciclo, per capirci qualcosa non basta una semplice linea (o anche meno) ... devi postare *tutto* il codice in modo fa poterlo esaminare in dettaglio. Non siamo indovini ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  5. #5
    Utente di HTML.it L'avatar di gaten
    Registrato dal
    Jul 2007
    Messaggi
    1,269
    client.c :
    codice:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include "client.h"
    
    int main(int argc,char* argv[])
    {
    	int SocketDescriptor;
    	int Port;
    	int length;
    	char Buffer[2]="";
    	int i;
    		
    	/* Verifico se ho inserito due parametri a linea di comando */
    	if ( argc == 3 )
    	{	
    		/* Converto in intero il valore della porta */
    		Port=atoi(argv[2]);
    		/* Creo e connetto il socket */
    		SocketDescriptor=CreateSocket(argv[1],Port);
    	}
    	else
    	{
    		printf("Specifica Indirizzo IP e Porta\n");
    		exit(1);
    	}	
    
    	for(;;)
    	{
    		/* Visualizzo comandi accettati dal client */
    		StampaCmdValidi();
    		
    		
    		length=read(0,Buffer,MAX_LEN);
    
    		write(1, "Comando scelto:\t", strlen("Comando scelto:\t"));
    		Buffer[length-1]='\0';
    		write(1, Buffer, MAX_LEN);
    		printf("len: %d\n", strlen(Buffer));
    
    		if (strlen(Buffer) == 2)
    		{
    			/* Il comando FM non viene inviato al server */
    			if (strcmp(Buffer, "FM") == 0)
    			{
    				write(1, "Container fermo. .\n", strlen("Container fermo. .\n"));
    			}
    			else
    			{
    				SendMessage(SocketDescriptor, Buffer);
    			}		
    		}
    		else if (strlen(Buffer) != 2)
    		{
    			write(1, "Error: Comandi validi {ST, PO, UP, SX, DN, RX, FM}. .\n", strlen("Error: Comandi validi {ST, PO, UP, SX, DN, RX, FM}. .\n"));
    		}	
    
    		/* Svuoto il buffer */
    		memset(Buffer, 0, MAX_LEN);
    	}
    	
    	return 0;
    }
    
    void StampaCmdValidi()
    {
    	write(1, "_________________________________________\n", strlen("_________________________________________\n"));
    	write(1, "COMANDI VALIDI:\n", strlen("COMANDI VALIDI:\n"));
    	write(1, "ST: Richiede le statistiche al server\n", strlen("ST: Richiede le statistiche al server\n"));
    	write(1, "PO: Richiede la posizione corrente del container\n", strlen("PO: Richiede la posizione corrente del container\n"));
    	write(1, "UP, DN, RX, SX: Comandi di spostamento\n", strlen("UP, DN, RX, SX: Comandi di spostamento\n"));
    	write(1, "FM. Questo comando NON viene inviato al server ed indica la necessitÃ_ di tenere il container fermo nel round corrente\n",
    	strlen("FM. Questo comando NON viene inviato al server ed indica la necessitÃ_ di tenere il container fermo nel round corrente\n"));
    	write(1, "_________________________________________\n", strlen("_________________________________________\n"));
    }
    
    void CloseSocket(int Socket)
    {
    	close(Socket);
    }
    
    int CreateSocket(char *Address, int Port)
    {
    	struct sockaddr_in *MyAddress; 
    	int Socket;
    	int Error;
      
    	/* Indirizzo */
    	MyAddress = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
    	MyAddress->sin_family=AF_INET;
    	MyAddress->sin_port=htons(Port);
        	if (inet_aton(Address, &MyAddress->sin_addr) == 0)
    	{
    		printf("Indirizzo IP non valido\n");
    		exit(2);	
    	}
    	
    	/* Creazione socket */ 
    	Socket=socket(AF_INET,SOCK_STREAM,0);
      
    	//Connessione del socket. Esaminare errore per compiere azioni
    	//opportune in caso di errore.
    	
    	Error=connect(Socket, (struct sockaddr*)MyAddress, sizeof(struct sockaddr_in));
    	
    	if ( Error < 0 )
    	{
    		perror("\nConnessione fallita..: ");
    		exit(0);
    	}
      
    	return Socket;
    }
    
    void SendMessage(int Socket, char *Message)
    {
    	printf("\nClient: %s\n",Message);
    	
    	//Si puo' notare il semplice utilizzo di write: 
    	//write(socket, messaggio, lunghezza messaggio)
    	
    	if (write(Socket, Message, strlen(Message)) <0)
    	{
    		write(1, "\nImpossibile mandare il comando.\n", strlen("\nImpossibile mandare il comando.\n"));
    		//CloseSocket(Socket);
    		exit(1);
    	}  
    	
    	printf("\nMessaggio spedito con successo.\n");
    }
    server.c :
    codice:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <errno.h>
    #include <pthread.h>
    #include <time.h>
    #include "server.h"
    
    
    int main(int argc, char* argv[])
    {
    	int SocketDescriptor, ConnectedSocket;
    	char Buffer[MAX_LEN]="";
    	int ExitCond=0;
    	int length;
    	int N, T, i;
    	int Error;
    	SCALO *Scalo;
    	pthread_t *Threads;
    	int r;
    	fd_set fds;
    	struct timeval tv;
    	tv.tv_sec=0;
    	tv.tv_usec=0;
    	int s;
    
    	//static const char *CMD[] ={"UP", "DN", "SX", "DX"};
    	
    
    	// Controllo che siano inseriti gli argomenti richiesti
    	if (argc != 3)
    	{
    		printf("Argomenti mancanti\n");
    		exit(1);
    	}
    	
    	/* Dimensione scalo */
    	N=atoi(argv[1]);
    
    	/* Alloco un puntatore a pthread_t */
    	Threads=(pthread_t*)malloc(sizeof(Threads)*(N*N));
    
    	/* tempo del round */
    	T=atoi(argv[2]);
    
    	/* Inizializziamo lo scalo */
    	Scalo=InitScalo(N, T);	
    
    	/* Stampo lo scalo */
    	StampScalo(Scalo);
    	printf("Num collisioni: %d\n", Scalo->NumCollisions);
    	printf("Num containers: %d\n", Scalo->NumContainers);
    	printf("Interv Round: %d\n", Scalo->IntervRound);
    	printf("Dim: %d\n", Scalo->Dim);
    
    	/* Creo e metto a disposizione il socket */
    	SocketDescriptor=InitSocket(4502);
    
    	printf("\nServer: Attendo connessioni...\n");
    
    
    	/* loop */
    	for(;;)
    	{	
    		/* Tempo da attendere prima di passare al prossimo round */
    		for (i=1; i<=T; i++)
    		{
    			sleep(1);
    			sprintf(Buffer, "%d\n", i);
    			write(1, Buffer, sizeof(Buffer));
    		}
    		sleep(1);
    		printf("Attendo connessioni. . .\n");
    	
    		if( (ConnectedSocket=accept(SocketDescriptor, NULL, NULL)) < 0 ) // La accept restituisce -1 alla seconda iterazione
    		{	
    			printf("Err: %s", strerror(errno));
    			/* Significa che il socket è non bloccante e non ci sono connessioni in attesa */
    			if (errno == EWOULDBLOCK)
    			{
    				write(1, "Nessuna connessione in attesa. .\n", strlen("Nessuna connessione in attesa. .\n"));
    			}
    	        	/* Non ho alcuna richiesta però i thread devono continuare l'esecuzione
    	           	   schiftando verso la fine dello scalo */
    		}
    		else /* Gestisci la richiesta del client */
    		{	
    			/* Con questo risolvo il problema della read(essendo bloccante), ora faccio la read solo se c'è qualcosa
    			   da leggere, quindi solo se scrivo qualcosa sul socket */
    			FD_ZERO(&fds);
    			FD_SET(ConnectedSocket, &fds);
    
    			r = select(ConnectedSocket+1,&fds, NULL, NULL, &tv);	
    			
    			if(r == 1)
    			{
    				length=read(ConnectedSocket, Buffer, MAX_LEN); // Questa read prima bloccava tutto
    				printf("Conn S dopo read%d\n", ConnectedSocket);
    				/* Controllo che il comando inviato sia corretto */
    				if ( (strlen(Buffer) == 2) && 
    			     	     (strcmp(Buffer, "UP") == 0) ||
    			     	     (strcmp(Buffer, "DN") == 0) ||
    			     	     (strcmp(Buffer, "SX") == 0) ||
    			     	     (strcmp(Buffer, "DX") == 0) )
    				{
    					/* Posso creare il thread ed eseguire il comando */
    					write(1, "Comando accettato -> Creazione thread. .\n", strlen("Comando accettato -> Creazione thread. .\n"));
    					pthread_create( (Threads+Scalo->NumContainers), NULL, Round, (void*)Buffer );
    			
    			
    					Scalo->NumContainers++; /* Incremento i containers */
    				}
    				else
    				{
    					write(1, "Comando non accettato. .\n", 25);
    				}
    			
    		    		/* Svuoto il buffer */
    				memset(Buffer, 0, MAX_LEN);	
    			}	
    		}
    	}
    
    	return 0;
    }
    
    
    SCALO *InitScalo(int Dim, int IntervRound)
    {
    	SCALO *Scalo;
    	int i, j;
    
    	Scalo=(SCALO*)malloc(sizeof(SCALO));
    
    	Scalo->Dim=Dim;				
    	Scalo->IntervRound=IntervRound;		
    	Scalo->NumContainers=0;			
    	Scalo->NumCollisions=0;
    
    	Scalo->Pos_Containers=(POS_CONTAINER*)malloc(sizeof(POS_CONTAINER)*(Dim*Dim));
    
    	for (i=0; i<Dim*Dim; i++)
    	{
    		Scalo->Pos_Containers[i].PosX=0;
    		Scalo->Pos_Containers[i].PosY=0;
    	}	
    
    	Scalo->Containers=(CONTAINER**)malloc(sizeof(CONTAINER*)*Dim);
    
    	for (i=0; i<Dim; i++)
    	{
    		Scalo->Containers[i]=(CONTAINER*)malloc(sizeof(CONTAINER)*Dim);
    		for (j=0; j<Dim; j++)
    		{	
    			Scalo->Containers[i][j].PosX=i;
    			Scalo->Containers[i][j].PosY=j;
    			Scalo->Containers[i][j].Occupato=LIBERO;
    		}
    	}
    
    	return Scalo;
    }
    
    
    void StampScalo(SCALO *Scalo)
    {
    	int i, j;
    
    	for (i=0; i<Scalo->Dim; i++)
    	{
    		for (j=0; j<Scalo->Dim; j++)
    		{	
    			printf("%d ", Scalo->Containers[i][j].Occupato);		
    		}
    		printf("\n");
    	}
    }
    
    int InitSocket(int Porta)
    {
    	int Socket;
    	struct sockaddr_in *MyAddress;
    
    	/* Indirizzo */
    	MyAddress=(struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
    	MyAddress->sin_family=AF_INET; // Protocolli di rete
    	MyAddress->sin_port=htons(Porta);
    	MyAddress->sin_addr.s_addr=INADDR_ANY; // Consente di raggiungere il servizio da tutte le interfacce
    	//inet_aton("127.0.0.1", &myaddress->sin_addr);
    	
    	/* Creo il socket */
        	Socket=socket(AF_INET, SOCK_STREAM, 0);
    
        	/* verifico se ritorna correttamente il socket descriptor */
        	if (Socket < 0)
        	{
            	perror("\nErrore nella creazione del socket: ");
            	exit(0);
        	}
    
    	/* Rendo il socket non bloccante in modo tale che se non ho una richiesta
              * continuo la normale esecuzione dei thread */
    	fcntl(Socket, F_SETFL, O_NONBLOCK); // Setto il flag del fd come O_NONBLOCK
    
    	/* verifico se assegna correttamente l'indirizzo al canale di comunicazione */
    	if (bind(Socket, (struct sockaddr *)MyAddress, sizeof(struct sockaddr_in)) < 0 )
        	{
            	perror("\nErrore assegnazione indirizzo al socket..");
            	exit(1);
        	}
    
    	/* Pone il socket in attesa di una connessione, accetta al massimo
     	     MAX_REQUEST richieste contemporanemente */
    	if (listen(Socket,5)<0)
    	{
            	perror("\nErrore listen al socket..");
    		exit(2);
        	}
    
        	return Socket;
    }
    
    
    void CloseSocket(int Socket)
    {
    	close(Socket);
    }
    
    void *Round(void *arg)
    {
    	char c=(char)arg;
    
    	pthread_mutex_lock(&mutex); /* Acquisisco il mutex */
    	/* Sezione critica */
    	printf("Il comando e' arrivato correttamente ed e': %c", c);
    	/* Fine sezione critica */
    	pthread_mutex_unlock(&mutex); /* Rilascio il mutex */
    }
    Con i sogni possiamo conoscere il futuro...

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 © 2025 vBulletin Solutions, Inc. All rights reserved.