Problema Socket lato Server

di il
5 risposte

Problema Socket lato Server

Buonasera a tutti, sto facendo un po' di esperimenti con la programmazione di rete e in questo momento sto creando un Server, che letta una stringa dalla socket (inviata ovviamente da un client che riceve in input da tastiera tale stringa ), restituisce al client la lunghezza di tale stringa. Per la prima stringa il server funziona correttamente e mi viene stampato il risultato giusto, però ora vorrei porre una piccola modifica: vorrei che il server non interrompa la connessione, ma lo faccia solo quando la socket del client si chiude. Insomma il client può inviare "ciao " e stampa 4 poi riscrive albero e stampare 6 , ma ciò non accade perché dopo la stringa ciao il Server o meglio il figlio del mio processo server termina la connessione e non rimane in attesa di altro. Avete delle idee?
#include<sys/types.h> /* predefined types */
#include<unistd.h> /* include unix standard library */
#include<arpa/inet.h> /* IP addresses conversion utililites */
#include<sys/socket.h> /* socket library */
#include<stdio.h> /* include standard I/O library */
#include <stdlib.h>
#include <string.h>

#define MAXLINE 256

int main (int argc , char *argv[])
{
 int list_fd,conn_fd;
 int i,nread;
 struct sockaddr_in serv_add,client;
 char buffer[1024],bufferStr[1024];
 socklen_t len;
 pid_t pid;
 int logging =1;

 if ((list_fd=socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("Socket error"); exit(1);}


 serv_add.sin_family=AF_INET;
 serv_add.sin_addr.s_addr=htonl(INADDR_ANY);
 serv_add.sin_port= htons(1024);


 if (bind(list_fd,(struct sockaddr *)&serv_add, sizeof(serv_add)) < 0 ){ perror("Bind error "); exit(1);}

 if (listen(list_fd,1024) < 0 ){ perror("Listen error "); exit(1);}

 while(1)
	{
	 len = sizeof ( client );

    if( (conn_fd=accept(list_fd,(struct sockaddr *)&client,&len)) <0 ){ perror("Accept error"); exit(1);}


	 /* fork to handle connection */
	 if((pid= fork())<0)
		{
		 perror (" fork error ");
		 exit ( -1);
		}
	 if(pid==0)
		{ /* child */
		 close ( list_fd );
		 //[u][b] Credo che io debba modificare il corpo del while ma non riesco a capire come [/b][/u]
		 //leggo la stringa presente nella socket e la metto in bufferStr
		 while((nread=read(conn_fd,bufferStr,1024)) != 0){
		  if (nread < 0) {
			 perror("Errore in lettura");
			 return 1;
		  }
		  bufferStr[nread]=0;
		  //Scrivo in bufferStr la lunghezza della stringa presente in bufferStr (sovrascivo il contenuto)
		  snprintf(bufferStr,sizeof(bufferStr),"%d\n",(int)strlen(bufferStr)-1);

		  // scrivo nella socket ciò che è presente un bufferStr
		  write(conn_fd,bufferStr,sizeof(bufferStr));
 		  if(logging)
			 {
			 // Stampo i dati di chi mi ha contattato
			  inet_ntop(AF_INET,&client.sin_addr,buffer,sizeof(buffer));
			  printf("Request from host %s, port %d\n",buffer,ntohs(client.sin_port));
			 }
		 }
         close(conn_fd);
 		 exit (0);
		}
	 else
		{ /* parent */
		 close ( conn_fd );
		}
	}
 /* normal exit , never reached */
 exit (0);
}

Questo è il client se può servire a qualcuno
#include <sys/types.h>   /* predefined types */
#include <unistd.h>      /* include unix standard library */
#include <arpa/inet.h>   /* IP addresses conversion utiliites */
#include <sys/socket.h>  /* socket library */
#include <stdio.h>	 /* include standard I/O library */
#include <errno.h>	 /* include error codes */
#include <string.h>	 /* include erroro strings definitions */
#include <stdlib.h>
#define MAXLINE 256

void ClientEcho(FILE * filein, int socket);


int main(int argc, char *argv[])
{
    int sock, i;
    int reset = 0;
    struct sockaddr_in serv_add;

    if ( (sock=socket(AF_INET,SOCK_STREAM,0)) < 0 ) {perror("Socket error "); exit (1);}

    serv_add.sin_family=AF_INET;
    serv_add.sin_port=htons(1024);

    if (inet_pton(AF_INET, argv[1], &serv_add.sin_addr) <0) {perror("PTON error "); exit (1);}


    if (connect(sock,(struct sockaddr *)&serv_add,sizeof(serv_add)) <0 ) { perror("Connect error "); exit(1);}
    // passo il file da cui prendere l'input cioè dalla tastiera e il fd in cui deve scrivere
    ClientEcho(stdin, sock);
    /* normal exit */
    return 0;

}

void ClientEcho(FILE * filein, int socket)
{
    char sendbuff[MAXLINE+1], recvbuff[MAXLINE+1];
    int nread, nwrite;

	while (1) {
	// prendo dallo stadinp e metto in send buff (equivale ad una scanf quindi il processe attende che inserisco qualcosa)
	    if (fgets(sendbuff, MAXLINE, filein) == NULL) { /* if no input */
                close(socket);
                return;                /* we stopped client */
            } else { /* else we have to write to socket */
                 //scrivo il contenuto di sendbuff nella socket cosi da inviarlo al server
                 write(socket,sendbuff,MAXLINE);

            }
            //il server mi restituisce la lunghezza della stringa contenuta in send buff e la inserisco n recvbuff
           nread=read(socket,recvbuff,MAXLINE);

            if (nread < 0)
            {
                fprintf(stderr,"read error\n");
                exit(1);
            }
            else if (nread==0)
            {
                fprintf(stderr,"nread=0\n");
                exit(1);
            }
            // se la lettura è andata a buon fine stampo con la fputs la stringa in recvbuff
             recvbuff[nread] = 0;
                printf("Numero di caratteri:\n");
            if (fputs(recvbuff, stdout) == EOF) {
			perror("Errore in scrittura su terminale");
			return;
            }
            }

    }


5 Risposte

  • Re: Problema Socket lato Server

  • Re: Problema Socket lato Server

    Se fosse stato ovvio per me non avrei scritto sul forum non credi? Se tanto ti pesa rispondere semplicemente non farlo. Comunque ti ringrazio lo stesso ma non so vorrei almeno capire se c'è una soluzione "ottimizzata" per fare la stessa cosa senza riempire il mio codice di cicli su cicli, ovviamente se possibile. E comunque se volessi provare questa soluzione poi l'uscita del figlio e la chiusura della descrittore di connessione dove devo farla? Quando esce dal while ( e quale dovrebbe essere il predicato)?
  • Re: Problema Socket lato Server

    Ma chi ti dice che mi pesa rispondere? Polemiche inutili...

    Ti ho suggerito come fare e se vuoi provi a scrivere qualcosa, fermo restando che continua a sembrarmi una soluzione ovvia.
  • Re: Problema Socket lato Server

    oregon ha scritto:


    Ma chi ti dice che mi pesa rispondere? Polemiche inutili...

    Ti ho suggerito come fare e se vuoi provi a scrivere qualcosa, fermo restando che continua a sembrarmi una soluzione ovvia.
    Lasciamo stare le polemiche, ma il tono con cui mi hai risposto sapeva di saccenteria. Comunque ho provato, ma non cambia nulla,probabilmente non mi è molto chiaro sto ciclo come deve essere...
  • Re: Problema Socket lato Server

    Il tono si sente dalla voce non da frasi scritte.

    Se non ha funzionato mostra cosa hai scritto.
Devi accedere o registrarti per scrivere nel forum
5 risposte