Visualizzazione dei risultati da 1 a 6 su 6
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    97

    client- server linguaggio c

    Salve amici, sto facendo un esercizio client - server in c praticamente avvio il server e ogni qual volta avvio il client, il server gli invio un messaggio dicendogli il numero di volte che ha contattato il server .
    Esempio avvio il client 1 volta, e mi stampa sul client : il server è stato contattato una volta.
    avvio il client 2 volte, e mi stampa sul client : il server è stato contattato 2 volte e così via.
    Questa cosa l'ho fatta, adesso però devo complicare l'esercizio, praticamente il client deve passare al server il nome dell'utente (letto da stdin da parte del client) nel messaggio di richiesta, e deve modificare il messaggio di risposta prodotto dal server in modo che contenga anche il nome dell'utente.

    Qualcuno ha suggerimenti perfavore ?? grazie mille

  2. #2
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,466
    E quale sarebbe il codice che hai già scritto?
    Sai come si inviano dati dal client al server?
    Ambiente di lavoro (linux, windows)?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    97
    Ciao oregon il mio ambiente di lavoro e osx.
    Sto studiando da poco il protocollo TCP e dovrei fare questo esercizio in c.
    Il codice del client è il seguente:
    codice:
    #include <sys/types.h>#include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    
    
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    
    #define PROTOPORT  5193  /* default port number */
    
    
    extern  int  errno;
    char localhost[] = "127.0.0.1"; /* localhost è una variabile che tiene traccia
                                    dell'indirizzo di default,questo è un'indirizzo
                                    particolare perche rappresenta su qualsiasi
                                    macchina, la macchina stessa. Mi permette 
                                    la comunicazione tra processi che sono sulla 
                                    stessa macchina*/
    
    
    int main(int argc, char *argv[]) {    /* Il primo parametro, se specificato da riga di comando
                                          va a sostituire l'indirizzo IP di default, invece
                                          il secondo parametro se specificato, va a sostituire
                                          il numero di porta di default*/
      struct  sockaddr_in sad; /* structure to hold an IP address del server    */
      int     sd;              /* socket descriptor                   */
      int     port;            /* protocol port number, che può essere messo di
                                default o da riga di comando                */
      int     n;               /* number of characters read           */
      char    buf[1000];       /* buffer for storing data from the server     */
      char    *host;  
    
    
      memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure   */
      sad.sin_family = AF_INET;         /* set family to Internet       */
      
    
    
      /* Questi due if di seguito, vanno a sostituire, rispettivamente, il numero di porta 
        e l'indirizzo IP, se e solo se sono specificati come parametri del main altrimenti
        vengono utilizzati quelli di default*/
      if (argc > 2) {                   /* if protocol port specified   */
        port = atoi(argv[2]);           /* convert to binary            */
      } else {
        port = PROTOPORT;               /* use default port number      */
      }
      if (port > 0)                     /* test for legal value         */
        sad.sin_port = htons((u_short)port);
      else {                            /* print error message and exit */
        fprintf(stderr,"bad port number %s\n",argv[2]);
        exit(1);
      }
    
    
      /* Check host argument and assign host name. */
      if (argc > 1) {
        host = argv[1];    /* if host argument specified   */
      } else {
        host = localhost;
      }
    
    
      sad.sin_addr.s_addr = inet_addr(host);
      
      /* Create a socket. */
      sd = socket(PF_INET, SOCK_STREAM, 0);
      if (sd < 0) {
        fprintf(stderr, "socket creation failed\n");
        exit(1);
      }   
     
      if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
        fprintf(stderr, "connect failed\n");
        exit(1);
      }
      
      
      
      
    
    
      n = read(sd, buf, sizeof(buf)); 
      while (n > 0) {
        write(1, buf, n);
        n = read(sd, buf, sizeof(buf));
      }
      /* Close the socket. */
      close(sd);
      /* Terminate the client program gracefully. */
      exit(0);
    }

    Il codice del server è questo:

    codice:
    #include <sys/types.h>#include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    
    #define PROTOPORT   5193 /* numero di porta di default */
    #define QLEN        6    /* coda richieste di connessione        */
    
    
    int visits = 0;          /* variabile che conta le connessioni del client al server */
    
    
    int main(int argc, char *argv[]) {
      struct  sockaddr_in sad; /* struttura sockaddr_in,indirizzo del server  */
      struct  sockaddr_in cad; /* struttura sockaddr_in, indirizzo del client  */
      int     sd, sd2;         /* due descrittori socket,perche stiamo utilizzando
                                un modello orientato ai flussi,quindi uno sta a 
                                rappresentare la socket di contatto e l'altra la 
                                socket di connessione */
      int     port;          /* protocol port number */
      int     alen;          /* length of address  */
      char    buf[1000];       /* buffer utilizzato per inviare il messaggio */
      
      memset((char *)&sad, 0, sizeof(sad));   /* clear sockaddr s. */
      sad.sin_family = AF_INET;             /* set family to Internet */
      sad.sin_addr.s_addr = htonl(INADDR_ANY);  /* set the local IP addr  */
      
      if (argc > 1) {                         /* se l'argomento specificato è
                                    maggiore di 1, vuol dire che è stato 
                                    specificato un numero di porta da riga
                                    di comando il quale viene poi convertito
                                    in una stringa */
         port = atoi(argv[1]);              
       } else {
         port = PROTOPORT;                  /* altrimenti viene usato il numero
                                            di porta di default     */
       }
    
    
       /* Verify port number */
       /* … */
    
    
      sad.sin_port = htons((u_short)port);  /* Assegniamo quindi il numero di
                                            porta,e lo convertiamo con una 
                                            rappresentazione esterna*/
    
    
      /* A questo punto abbiamo pronto l'indirizzo di trasporto*/
       
      /* Creiamo la socket */
      sd = socket(PF_INET, SOCK_STREAM, 0);
      
      if (sd < 0) {
       fprintf(stderr, "socket creation failed\n");
       exit(1);
      }
      /* Effettua la Bind sull'indirizzo locale della socket */
      if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) {
         fprintf(stderr,"bind failed\n");
         exit(1);
      }
      /* Da questo momento in poi, se la Bind non è fallita,la socket
       del server può accettare connessioni, e attraverso la listen si va a 
       specificare la coda di lunghezza delle connessioni */
      if (listen(sd, QLEN) < 0) {
         fprintf(stderr,"listen failed\n");
         exit(1);
      }
    /* Vogliamo che il server rimanga in ascolto del client teoricamente 
    all'infinito per questo utilizziamo il ciclo while*/
      while (1) {
         alen = sizeof(cad);
    
    
         /* Viene invocata la funzione accept sul descrittore sd e restituisce
         ancora un'intero; estra una connessione dalla coda di connessioni
         la quale duplica la struttura di origine e si completa con le 
         informazioni del client che si è connesso al server
         La conversazione avverrà attraverso la socket sd2*/
         if ( (sd2=accept(sd, (struct sockaddr *)&cad, &alen)) < 0) {
          fprintf(stderr, "accept failed\n");
          exit(1);
         }
    
    
         /* Dopo l'accept posso utilizzare la read; nel caso specipico il contatto
         è avvenuto tramite la connessione, quindi abbiamo sfruttato la richiesta di
         connessione la quale mi ha garantito il contatto,quindi andiamo a incrementare
         la variabile visit e andiamo a scrivere il messaggio di risposta*/
    
    
         visits++;
         /*funzione fprintf scrive sul file, sprintf scrive su un buffer e bisogna
         specificare sempre il nome dell'array prima di stampare a video ciò che
         si desidera, in questo caso il nome dell'array è buf*/
         sprintf(buf, "This server has been contacted %d time%s\n", visits, visits==1 ? "." : "s.");
         /* Con la funzione write, scriverò nel buffer la stringa,questa roba si
         trova nel buffer associata della socket di connessione sd2*/
         write(sd2, buf, strlen(buf));  
         close (sd2); /* Sto chiudendo la socket di connessione utilizzata 
         per conversare con lo specifico client. La variabile sarà disponibile 
         per un'ulteriore connessione con un'altro client.
         sd non l'abbiamo chiusa, altrimenti chiuderemo la socket del server.*/
       }
    }
    Praticamente in questo modo ogni volta che avvio il client, il server gli invia un messaggio indicando il numero di volte che il server è stato contattato.
    Ora dovrei modificarlo, chiedendo al client di inserire il mio nome e successivamente quando il client contatta il server deve inviare al client un messaggio nel quale oltre a dire quante volte è stato contattato il server, nel messaggio deve comparire il mio nome, esempio "gigi ha contattato il server 5 volte"

  4. #4
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    97
    non sò se sono stato chiaro nella spiegazione dell'esercizio, spero di si.
    In attesa di qualche suggerimento auguro a tutto il forum un augurio di Buon Natale a tutti voi!!

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    97
    oregon ho modificato il codice e nel client ho aggiunto:
    codice:
      printf("Digita il tuo nome: ");
      fgets(buf,999);
      n = write(sd, buf, strlen(buf));  //quinscrivo il nome nel buffer per inviarlo al server
       n = read(sd, buf, sizeof(buf)); 
      while (n > 0) {
        write(1, buf, n);
        n = read(sd, buf, sizeof(buf));
      } 
      
    
    
      /* Close the socket. */
      close(sd);
      /* Terminate the client program gracefully. */
      exit(0);
    }

    la mia difficoltà ora sta nel server non so come far leggere il nome digitato nel client dal server, ho fatto in questo modo ma non me lo stampa il nome:
    codice:
     n = read(sd2, buf, 999);     visits++;
        
         sprintf(buf, "%s This server has been contacted %d time%s\n", buf, visits, visits==1 ? "." : "s.");
        
         write(sd2, buf, strlen(buf));  
         close (sd2); 
       }
    }
    Io non ho capito se il nome che digito lo devo salvare in un buffer diversooppure va bene come ho fatto, utilizzando buf. Mi potresti consigliare come risolvere questo problema?Grazie mille

  6. #6
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    97
    non c'è nessuno che mi può aiutare perpiacere??

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.