Dom 18 Agosto, 06:52:39 - 2019

Autore Topic: Problema invio-ricezione stringhe al Server  (Letto 1544 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Peprunner

  • Studente
  • *
  • Post: 43
  • FeedBack: +0/-0
    • Mostra profilo
Problema invio-ricezione stringhe al Server
« il: Sab 23 Aprile, 16:40:49 - 2016 »
Sono alle prese con la tesina e ho un problema riguardo l' invio e la ricezione di stringhe mediante socket.
In poche parole quando invio l' username, ad esempio "Marco", in ricezione sul server non ho la stringa "Marco", ma "Marco�y�". Idee??


**CODICE CLIENT**
char user[6];
printf("Inserire l' Username (5 caratteri)\nUsername:");
   scanf("%s",user);
   write (socket_remoto,&user,strlen(user));



**CODICE SERVER** 

char user[6]
caratteri=read(socket_cliente, user, 6);
   if (caratteri<=0){
      perror ("read");
      return (-1);
   }
printf("questo è l' user: %s\n",user);

Offline Bersa125

  • Studente
  • *
  • Post: 1
  • FeedBack: +0/-0
    • Mostra profilo
Re:Problema invio-ricezione stringhe al Server
« Risposta #1 il: Sab 23 Aprile, 19:25:21 - 2016 »
Siccome ho riscontrato e risolto un problema simile nella mia tesina posso consigliarti di sovrascrivere forzatamente il carattere del buffer che si trova all'indice successivo alla lunghezza della stringa con il carattere di terminazione '\0'.

Ad esempio con il codice da te postato e con l'input "Marco" abbiamo che la lunghezza della stringa è 5, quindi user sarà occupato dall'input nelle celle da 0 a 4. in user[5] dovrai inserire '\0'.

Quei caratteri casuali ti vengono mostrati sul server in quanto l'ultima cella dell'array potrebbe non essere stata inizializzata prima dell'invio.

In caso di input di lunghezza n bisogna allocare sempre buffer di grandezza n+1 per questo motivo.

Ti sconsiglio inoltre di usare scanf per acquisire gli input in quanto il professore non la accetta come soluzione. Al suo posto potresti usare fgets o una read sull'input standard con i dovuti accorgimenti  ;).

Offline Peprunner

  • Studente
  • *
  • Post: 43
  • FeedBack: +0/-0
    • Mostra profilo
Re:Problema invio-ricezione stringhe al Server
« Risposta #2 il: Mer 27 Aprile, 13:52:12 - 2016 »

Ho provato in questo modo:
Codice: [Seleziona]
**CODICE CLIENT**
char user[5];
printf("Inserire l' Username (5 caratteri)\nUsername:");
fgets(user,5,stdin);
write (socket_remoto,&user,strlen(user));


**CODICE SERVER** 

char user[5]
caratteri=read(socket_cliente, user, 5);
if (caratteri<=0){
  perror ("read");
  return (-1);
}
printf("questo è l' user: %s\n",user);

ma quando arriva sull' istruzione dell' fgets considera l' input come se fosse già stato inserito senza che lo abbia effettivamente inserito. In poche parole esegue direttamente la write sul socket.

Offline Kernel

  • Global Moderator
  • Neo-Laureato
  • *****
  • Post: 57
  • FeedBack: +8/-0
    • Mostra profilo
Re:Problema invio-ricezione stringhe al Server
« Risposta #3 il: Lun 02 Maggio, 14:55:24 - 2016 »
Segui il consiglio di bersa125: devi aggiungere manualmente il terminatore di stringa \0.

Offline Peprunner

  • Studente
  • *
  • Post: 43
  • FeedBack: +0/-0
    • Mostra profilo
Re:Problema invio-ricezione stringhe al Server
« Risposta #4 il: Sab 07 Maggio, 02:20:10 - 2016 »
ho inserito il carattere terminatore '\0' prima dell' invio della stringa al server (quindi lato client), ma la situazione non è migliorata affatto. In alcuni casi l' fgets non attende l' inserimento dell' input e il programma salta sulle istruzioni successive. Come soluzione ho provato con fflush supponendo che il buffer fosse "sporco", ma anche in questo caso non sono riuscito a risolvere il problema. Vi posto il codice. Illuminatemi.  :D

Codice: [Seleziona]
***CLIENT***


int scrivimessaggio(int socket_remoto) {
int caratteri,permesso;
char user[5],pass[5];

fflush(stdin);
//inserimento username
memset(&user,0,5);
printf("Inserire l' Username (5 caratteri)\nUsername:");
fgets(user,6,stdin);
user[5]='\0';
write (socket_remoto,&user,strlen(user));


fflush(stdin);
//inserimento password
memset(&pass,0,5);
printf("\nInserire la Password (5 caratteri)\nPassword:");
fgets(pass,6,stdin);
pass[5]='\0';
write (socket_remoto,&pass,strlen(pass));


//esito user & pass
caratteri=read(socket_remoto,&permesso,sizeof(int));    //qua gli arriva riconosciuto di servi_scrivi_messaggio.h
printf("Permesso concesso %d \n", permesso);
if (permesso==0) {
printf("Username o Password non corretti\n");
printf ("***Autenticazione fallita***\n\n");
return (0);
}
else {
scrivi(socket_remoto,user);
}
return 0;






***SERVER***


int servi_scrivi_messaggio (int socket_cliente) {
FILE *fout,*fpass,*fd;
int caratteri,riconosciuto,numerostringhe=0,d;
char user[6],passw[6],userpsw[13],verifica[13],soggetto[MAX_BUFFER],data[9];
      if ((fpass=fopen ("passw.dat","r"))==NULL)
printf("err file pasw");

//leggo username
caratteri=read(socket_cliente, user, 6);
sleep(1);
if (caratteri<=0){
perror ("read");
return (-1);
}
printf("questo è user: %s\n",user);   //RIGA DA ELIMINARE
strcpy (userpsw,user);
strcat(userpsw,"-");

//leggo password
caratteri=read(socket_cliente, passw, 6);
sleep(1);
if (caratteri<=0){
perror ("read");
return (-1);
}
printf("questo è Pass: %s\n",passw);   //RIGA DA ELIMINARE
strcat(userpsw,passw);   //user + password

riconosciuto=0;
printf("questa è identita 1 %s\n",userpsw);     //RIGA DA TOGLIERE

// vado a verificare se la password presente sul socket è uguale a una di quelle presenti in passw.dat
// nel caso sia effettivamente così, settiamo riconosciuto ad 1
while ( (riconosciuto==0) && (!feof(fpass)) ){
fscanf (fpass,"%s",verifica);
printf("questa è verifica %s\n", verifica);   //RIGA DA TOGLIERE

if (strcmp(verifica,userpsw)==0) //comparazione stringa
                              riconosciuto=1;
}
fclose (fpass);
printf("questa è riconosciuto:%d\n",riconosciuto);      //RIGA DA TOGLIERE
write(socket_cliente,&riconosciuto,sizeof(int));
if (riconosciuto==0) /*break*/;
sleep(1);




Offline Kernel

  • Global Moderator
  • Neo-Laureato
  • *****
  • Post: 57
  • FeedBack: +8/-0
    • Mostra profilo
Re:Problema invio-ricezione stringhe al Server
« Risposta #5 il: Sab 07 Maggio, 13:52:47 - 2016 »
io ho fatto così

LATO CLIENT
Codice: [Seleziona]
printf("send: ");
fgets(buf, 1024, stdin);  //fgets prende anche il carattere invio
size_t buf_len = strlen(buf);
--buf_len; // remove '\n' from the end of the message

while ( (ret = send(args->desc, buf,buf_len, 0)) < 0 ) {
if (errno == EINTR) continue;
ERROR_HELPER(-1, "Cannot write to the socket");
}


e lato server aggiungo il '\0'

Offline Kernel

  • Global Moderator
  • Neo-Laureato
  • *****
  • Post: 57
  • FeedBack: +8/-0
    • Mostra profilo
Re:Problema invio-ricezione stringhe al Server
« Risposta #6 il: Sab 07 Maggio, 13:56:53 - 2016 »
comunque va bene anche il tuo codice però hai sbagliato ad usare gli indici

char user[5],pass[5];

   fflush(stdin);
   //inserimento username
   memset(&user,0,5);
   printf("Inserire l' Username (5 caratteri)\nUsername:");
   fgets(user,6,stdin);
   user[5]='\0';

infatti tu inizializzi l'array char user[5] questo vuol dire che gli indici vanno da 0 a 4
quindi quando fai user[5]='\0' esci fuori dagli indici. Per risolvere basta che inizializzi char user[6]

Offline Peprunner

  • Studente
  • *
  • Post: 43
  • FeedBack: +0/-0
    • Mostra profilo
Re:Problema invio-ricezione stringhe al Server
« Risposta #7 il: Dom 08 Maggio, 21:52:23 - 2016 »
E anche questa volta non sono riuscito a risolvere il problema. Ho fatto dei test con delle printf e lato client la stringa viene acquisita correttamente, mentre lato server risulta corrotta.
« Ultima modifica: Gio 12 Maggio, 03:31:03 - 2016 da Peprunner »

Offline Peprunner

  • Studente
  • *
  • Post: 43
  • FeedBack: +0/-0
    • Mostra profilo
Re:Problema invio-ricezione stringhe al Server
« Risposta #8 il: Mer 11 Maggio, 13:32:48 - 2016 »
Per i posteri: ;)
qui ho trovato un esempio illuminante che mi ha permesso di correggere il codice http://www.binarytides.com/server-clien ... ets-linux/
inoltre lascio un paio di funzioni per acquisire da standard input affinché non ci siano problemi di formattazione nell' invio di stringhe

Codice: [Seleziona]
//acquisizione interi da tastiera

int scrivi_intero(){
int ris=-1;
while(1){
char test=getchar();
if(test!='\n') ungetc(test,stdin);
char *p;
char *buf=NULL;
size_t count=0;
if(getline(&buf,&count,stdin)>0){
ris=strtoumax(buf,&p,10);
if(*p=='\n'||*p=='\0'){
break;
}
else printf("input non intero,riprova\n");
}
}
return ris;
}


//acquisizione stringhe da tastiera

int scrivi_frase(char* testo_ris, int max_dim){
int ret;
char test=getchar();
if(test!='\n') ungetc (test,stdin);
while(1){
char* app_line=NULL;
size_t count=0;
ret=getline(&app_line,&count,stdin);
if (ret<=max_dim+1 && ret>=0){
strcpy (testo_ris,app_line);
ret--;
testo_ris[ret]='\0';
break;
}
printf("stringa troppo lunga [max %d caratteri] o errore nell' inserimento, riprovare\n" , max_dim);
}
return 0;
}
« Ultima modifica: Gio 12 Maggio, 03:01:06 - 2016 da Peprunner »