PDA

Visualizza la versione completa : [C] Problema socket read e write


viridovix
05-08-2005, 23:03
IL codice che segue funzionante, l'ho realizzato in prospettiva del codice che postero' dopo e che invece mi da problemi.
Di seguito, server e client che si connettono attraverso socket in tcp, il client invia dei messaggi che vengono visualizzati dal server.
Quando dal client si inserisce la stringa "quit", il server invia un messaggio "fatto" al client che l ovisualizza. Il server chiude la connessione con il client e si mette in attesa di un ulteriore connessione da un altro client.

Codice server in c sotto Linux:
//prova server scambio stringhe in TCP
//
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
//
#define ERRORE_(x) {puts(x);exit(1);}
#define MAX_CODA 1
#define MAX_DIM 1024
//
int main(void)
{
int ds_sock,ds_sock_acc,ret,lenght;
char buff[MAX_DIM];
struct sockaddr_in server;
struct sockaddr client;
//
system("clear");
ds_sock=socket(AF_INET,SOCK_STREAM,0);
if (ds_sock==-1) ERRORE_("CHIAMATA SOCKET FALLITA!!");
//
server.sin_family=AF_INET;
server.sin_port=htons(1569);
server.sin_addr.s_addr=INADDR_ANY;
ret=bind(ds_sock,(struct sockaddr*)&server,sizeof(server));
if (ret==-1) ERRORE_("CHIAMATA bind FALLITA!!");
ret=listen(ds_sock,1);
if (ret==-1) ERRORE_("CHIAMATA listen FALLITA!!");
//
signal(SIGCHLD,SIG_IGN);
lenght=sizeof(client);
//
printf("in attesa di connessione da parte del client!!\n\n");
//
while(1)
{
while((ds_sock_acc=accept(ds_sock,&client,&lenght))==-1);
printf("client connesso!!\n\n");
if (fork()==0)
{ close(ds_sock);
do
{
read(ds_sock_acc,buff,MAX_DIM);
printf("messaggi client: %s\n",buff);
//getchar();
}
while (strcmp(buff,"quit")!=0);
write (ds_sock_acc,"\n\nfatto",10);
close(ds_sock_acc);
printf("\nclient disconnesso!!\n\n");
printf("\nin attesa di connessione da nuovo client!!\n\n");
exit(0);
}
else close(ds_sock_acc);
}//while(1)
}
__________________________________________________ _______________
codice client in c sotto Linux:

//client per invio stringhe
//
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
//#include <string.h>
#include <stdlib.h>
//
#define ERRORE_(x) {puts(x);exit(1);}
#define MAX_DIM 1024
#define MAX_CODA 3

int main(void)
{
char indserver[30];
char buff[MAX_DIM];
char risp[1];
int ds_sock,ret;
struct sockaddr_in client;
struct hostent *hp;
//
system("clear");
ds_sock=socket(AF_INET,SOCK_STREAM,0);
if (ds_sock==-1) ERRORE_("CHIAMATA socket FALLITA!!");
//
client.sin_family=AF_INET;
client.sin_port=htons(1569);
//
//strcpy(risp,"x");
printf("il server si trova su una macchina remota? s/n\n\n");
scanf("%s",risp);
while((strcmp(risp,"s")!=0)&&(strcmp(risp,"n")!=0))
{
printf("\nscelta sbagliata, ripetere!!\n\n");
printf("il server si trova su una macchina remota? s/n\n\n");
scanf("%s",risp);
}
if (strcmp(risp,"s")==0)
{
printf("\ninserire l'indirizzo del server\n\n");
scanf("%s",indserver);
}
else if (strcmp(risp,"n")==0) strcpy(indserver,"127.0.0.1");
//
signal(SIGINT,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
//
hp=gethostbyname(indserver);
client.sin_addr.s_addr=((struct in_addr*)(hp->h_addr))->s_addr;
//bcopy(hp->h_addr,&client.sin_addr,hp->h_lenght);
ret=connect(ds_sock,(struct sockaddr *)&client,sizeof(client));
if (ret==-1)
{
perror("CHIAMATA SISTEMA connect FALLITA!!");
exit(1);
}

//
printf("\nConnesso al server!!\n");
printf("\ndigitare le stringhe da trasferire,quit per terminare!!\n\n");
do
{
scanf("%s",buff);
write(ds_sock,buff,MAX_DIM);
}
while(strcmp(buff,"quit")!=0);
read(ds_sock,buff,MAX_DIM);
printf("\nmessaggio dal server%s\n\n",buff);
close(ds_sock);
}
-----------------------------------------------------------------------------------------------
Come detto questo codice funziona perfettamente.Invece ora ho tentato di creare un client che propone un menu di scelta . Se scelgo 'a' il server fa una cosa , se scelgo 'b' un altra , con 'c' avrebbe lo stesso effetto del "quit" del codice sopra.
Purtroppo nn va quando da scanf (dal client) inserisco il carattere ,il server nn fa nulla .

codice client:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
//#include <string.h>
#include <stdlib.h>
//
#define ERRORE_(x) {puts(x);exit(1);}
#define MAX_DIM 1024
#define MAX_CODA 3

int main(void)
{
char indserver[30];
char buff[MAX_DIM];
char risp[1];
char scelta[1];
int ds_sock,ret;
struct sockaddr_in client;
struct hostent *hp;
//
system("clear");
ds_sock=socket(AF_INET,SOCK_STREAM,0);
if (ds_sock==-1) ERRORE_("CHIAMATA socket FALLITA!!");
//
client.sin_family=AF_INET;
client.sin_port=htons(1569);
//
//strcpy(risp,"x");
printf("il server si trova su una macchina remota? s/n\n\n");
scanf("%s",risp);
while((strcmp(risp,"s")!=0)&&(strcmp(risp,"n")!=0))
{
printf("\nscelta sbagliata, ripetere!!\n\n");
printf("il server si trova su una macchina remota? s/n\n\n");
scanf("%s",risp);
}
if (strcmp(risp,"s")==0)
{
printf("\ninserire l'indirizzo del server\n\n");
scanf("%s",indserver);
}
else if (strcmp(risp,"n")==0) strcpy(indserver,"127.0.0.1");
//
//signal(SIGINT,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
//
hp=gethostbyname(indserver);
client.sin_addr.s_addr=((struct in_addr*)(hp->h_addr))->s_addr;
//bcopy(hp->h_addr,&client.sin_addr,hp->h_lenght);
ret=connect(ds_sock,(struct sockaddr *)&client,sizeof(client));
if (ret==-1)
{
perror("CHIAMATA SISTEMA connect FALLITA!!");
exit(1);
}

//
printf("\nConnesso al server!!\n");
//printf("\ndigitare le stringhe da trasferire,quit per terminare!!\n\n");
do
{ printf("\nscelta a/b, c x uscire :");
scanf("%s",scelta);
while(getchar()!='\n');
if (strcmp(scelta,"a")==0)
{ printf("prima opzione");
write(ds_sock,scelta[0],1);
}
else if (strcmp(scelta,"b")==0)
{ printf("seconda opzione");
write(ds_sock,scelta[0],1);
}
}
while(strcmp(scelta,"c")!=0);
read(ds_sock,buff,MAX_DIM);
printf("\nmessaggio dal server%s\n\n",buff);
close(ds_sock);
}
- - - - - ----------------------------------------------
codice server :
//scelta server
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//
#define ERRORE_(x) {puts(x);exit(1);}
#define MAX_CODA 1
#define MAX_DIM 1024
//
int main(void)
{
int ds_sock,ds_sock_acc,ret,lenght,n;
char buff[MAX_DIM];
struct sockaddr_in server;
struct sockaddr client;
//
system("clear");
ds_sock=socket(AF_INET,SOCK_STREAM,0);
if (ds_sock==-1) ERRORE_("CHIAMATA SOCKET FALLITA!!");
//
server.sin_family=AF_INET;
server.sin_port=htons(1569);
server.sin_addr.s_addr=INADDR_ANY;
ret=bind(ds_sock,(struct sockaddr*)&server,sizeof(server));
if (ret==-1) ERRORE_("CHIAMATA bind FALLITA!!");
ret=listen(ds_sock,1);
if (ret==-1) ERRORE_("CHIAMATA listen FALLITA!!");
//
signal(SIGCHLD,SIG_IGN);
lenght=sizeof(client);
//
printf("in attesa di connessione da parte del client!!\n\n");
//
while(1)
{
while((ds_sock_acc=accept(ds_sock,&client,&lenght))==-1);
printf("client connesso!!\n\n");
if (fork()==0)
{ close(ds_sock);
do
{
read(ds_sock_acc,buff,MAX_DIM);
printf("messaggi client: %s\n",buff);
}
while (strcmp(buff,"c")!=0);
write (ds_sock_acc,"\n\nfatto",10);
close(ds_sock_acc);
printf("\nclient disconnesso!!\n\n");
printf("\nin attesa di connessione da nuovo client!!\n\n");
exit(0);
}
else close(ds_sock_acc);
}//while(1)
}

-----------------------------------------------------------------------------------------------
nn riesco a capire xch qui il server nn riceve i caratteri e agisca di conseguenza.
In origine il codice era +complesso , asseconda della scelta del client il server faceva una chiamata ad una determinata funzione, ma visto che nn va nemmeno cosi ho preferito semplificare e incentrare sul problema.
Insomma mi pare che la read nn riceva il carattere giusto.
nn so pi DOVE SBATTERE.
SPERO VIVAMENTE IN UN AIUTO!!

alka
06-08-2005, 03:55
Le esortazioni all'interno dei titoli non sono ben tollerate, come indicato dal Regolamento (http://forum.html.it/forum/showthread.php?s=&threadid=862015) stesso del forum.

Tutti risponderanno in base alle proprie conoscenze e se potranno farlo, o quando ne avranno la voglia; le urgenze non esistono all'interno di un forum.

Inoltre, hai postato una marea di codice che costringe chi vorrebbe risponderti ad analizzare minuziosamente il tuo codice o a cercare di utilizzarlo per individuare l'errore.

Forse pi lecito che tu faccia una cernita e che posti solamente le parti significative del codice spiegando pi dettagliatamente qual il problema. Questa solo un'opinione/consiglio personale, mentre la prima una regola.

Correggo il titolo per il momento.

Ciao! :ciauz:

viridovix
06-08-2005, 16:03
chiedo scusa x il titolo , x il codice hai ragione x la lunghezza, ma i primi client e server sono funzionanti(quindi magari a qualcuno puo' essere anche utile),e li ho postati insieme agli altri due che nn funzionano xch essendo simili un confronto pensavo fosse utile.
Cmq ho specificato il problema x bene credo e pensavo che senza tutto il codice sarebbe stato difficile x chi legge farsi un'idea :(

viridovix
06-08-2005, 22:20
Tutto quel codice puo' mettere paura, quindi seguendo il giusto consiglio del mod cerchero' di eslpicare esattamente il problema. nn considerate il codice sopra.
Una volta che client e server sono collegati fra loro tramite socket con protocollo tcp,
il client offre all'utente ad esempio u nmenu di 3 scelte, da inserire tramite scanf o getchar,
l'utente puo inserire o il carattre a o il carattere b o il carattere c.( un ciclo da cui si esce con questo carattere)
Se inserisce il carattere c allora con la write viene spedito al server che l olegge con la read e che di conseguenza invia al client u nmessagio tipo "disconnessione in corso", poi chiude il socket e si mette in ascolto x un 'altra connessione .
Il client invece ricevuto il messaggio lo stampa a video e termina .

questa la parte di server interessata :

while(1)
{
while((ds_sock_acc=accept(ds_sock,&client,&lenght))==-1);
printf("client connesso!!\n\n");
if (fork()==0)
{ close(ds_sock);
do
{
read(ds_sock_acc,buff,MAX_DIM);
printf("messaggi client: %s\n",buff);
}
while (strcmp(buff,"c")!=0);
write (ds_sock_acc,"\n\nfatto",10);
close(ds_sock_acc);
printf("\nclient disconnesso!!\n\n");
printf("\nin attesa di connessione da nuovo client!\n\n");
exit(0);
}
else close(ds_sock_acc);
}//while(1)
}

questa del client :

do
{printf("\nscelta a/b, c x uscire :");
scanf("%s",scelta);
while(getchar()!='\n');
if (strcmp(scelta,"a")==0)
{ printf("prima opzione");
write(ds_sock,scelta[0],1);
}
else if (strcmp(scelta,"b")==0)
{ printf("seconda opzione");
write(ds_sock,scelta[0],1);
}
}
while(strcmp(scelta,"c")!=0);
read(ds_sock,buff,MAX_DIM);
printf("\nmessaggio dal server%s\n\n",buff);
close(ds_sock);
}

in pratica nn so xch ma i nquesto caso le read e write nn fanno il loro dovere, se inserisco ad esempio c , i lserver nn chiude la connessione e il client nn termina.

viridovix
08-08-2005, 20:52
Risolto aggiustando il codice e soprattutto aggiungendo questa:

in pratica dopo while(strcmp(scelta,"c")!=0);
ci voleva write(ds_sock,scelta,MAX_DIM); nel codice del client.

Loading