PDA

View Full Version : [C] Semplicissima socket e stringhe


xsatellitex
18-04-2008, 10:19
Devo fare una socket lato server che se riceve la stringa "prova" stampa a video "ok".Qui sotto riporto le linee di codice piu importanti... penso sia un problema di stringhe... il problema riguarda il confronto... mi sapete dire perche non va a buon fine se il server ovviamente riceve la stringa prova?

char buf[20];
recv(sd2,buf,sizeof(buf),0);
if (strcmp(buf,"prova") == 0) { printf("ok");}

aiuto :mc:

T-Jack
18-04-2008, 10:26
Scusa ma il primo parametro di strcmp() non dovrebbe essere "buf"?

xsatellitex
18-04-2008, 10:29
si scusa è buf ho corretto... ma lo stesso non funziona :cry:

T-Jack
18-04-2008, 10:31
Allora posta il resto del codice...

xsatellitex
18-04-2008, 10:39
#define closesocket close
#define PROTOPORT 6500
#define QLEN 6
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>

int visit=0; //variabile globale

main(argc,argv)
int argc;
char *argv[];

{

struct hostent *ptrh; //x chiamata dns contiene nome e lista alias, lunghezza e tipo indirizzo, lista indirizzi
struct protoent *ptrp; //nome protocollo e suo identificativo
struct sockaddr_in sad; //indirizzo ip e porta, ....
struct sockaddr_in cad;
int sd,sd2; //descrittori di socket
int port; //numero porta protocollo
int alen; //lunghezza indirizzo
char buf[20]; //buffer per la string da inviare
int n; //numero di caratteri ricevuti
int optval=1;

memset((char *)&sad,0,sizeof(sad)); //azzera il campo sad
sad.sin_family=AF_INET; //set family
sad.sin_addr.s_addr=INADDR_ANY; //set local ip address

if(argc>1){
printf("porta %d\n",port);
port=atoi(argv[1]); //converte stringa in numero
printf("porta in binario %d\n",port);
}
else{
port=PROTOPORT;
}

if(port>0){
sad.sin_port=htons((u_short)port); //trasforma in networkbyteorder ( cioe da little endian a big endian)

printf("porta in NetworkByteOrder %d\n",sad.sin_port);
}
else{
fprintf(stderr,"Numero di porta non valido %s\n",argv[1]);
exit(1);
}

if((int)(ptrp=getprotobyname("tcp"))==0){
//getprotobyname data una stringa che rappresenta un protocollo, fornisce il numero corrispondente

fprintf(stderr,"Cannot map tcp to protocol number");
exit(1);
}
printf("protocol %d\n",getprotobyname("tcp"));

printf("protocol cast int %d\n",(int)getprotobyname("tcp"));

if((sd=socket(AF_INET,SOCK_STREAM,ptrp->p_proto))<0){
fprintf(stderr,"Socket creation failed");
exit(1);
}
printf("socket creata sd %d\n",sd);

if(setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,(const void *)&optval,sizeof(int))<0)
{return -1;
}

if(bind(sd,(struct sockaddr *)&sad,sizeof(sad))<0){
fprintf(stderr,"Bind error\n");
exit(1);
}

if(listen(sd,QLEN)<0){
fprintf(stderr,"Listen Failed\n");
exit(1);
}


while(1){
alen=sizeof(cad);

if((sd2=accept(sd,(struct sockaddr *)&cad,&alen))<0){
fprintf(stderr,"Accept failed\n");
exit(1);
}
printf("socket client sd %d\n",sd2);

n=recv(sd2,buf,sizeof(buf),0);


while(n>0) {


if (strcmp(buf,"prova") == 0)
{ printf("ok");}

n=recv(sd2,buf,sizeof(buf),0);
}
closesocket(sd2);
}
}

T-Jack
18-04-2008, 11:07
Senti io ho buttato giu dieci rige di client per inviare la stringa "prova" e funziona regolarmente.. questo significa che:
1. Il client non fa il suo lavoro;
2. Problemi con firewall,routers...

ps. Il client a che indirizzo si connette?

xsatellitex
18-04-2008, 11:09
azzo e come mai a me no... ho provato altre socket e funzionano...questa no... pensavo che il problema riguardasse il confronto.... grazie per l'aiuto :)
Qui c'e' il client:
#define closesocket close
#define PROTOPORT 6500
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>

extern int errno;
char localhost[]="localhost";

int main(int argc,char *argv[])
{ struct hostent *ptrh;
struct protoent *ptrp;
struct sockaddr_in sad;
int sd;
int port;
char *host;
int n;
char buf[1000];
char *text;

memset((char *)&sad,0,sizeof(sad));
sad.sin_family=AF_INET;

if(argc>2){
port=atoi(argv[2]);
}
else{
port=PROTOPORT;
}

if(port>0){
sad.sin_port=htons((u_short)port);
}
else{
fprintf(stderr,"Numero di porta non valido",argv[2]);
exit(1);
}

if(argc>1){
host=argv[1];
}
else{
host=localhost;
}

ptrh=gethostbyname(host);

if(((char *)ptrh)==NULL){
fprintf(stderr,"Host non valido %s\n",host);
exit(1);
}

memcpy(&sad.sin_addr,ptrh->h_addr,ptrh->h_length);

if(((int)(ptrp=getprotobyname("tcp")))==0){
fprintf(stderr,"Cannot map tcp to protocol number\n");
exit(1);
}

if((sd=socket(AF_INET,SOCK_STREAM,ptrp->p_proto))<0){
fprintf(stderr,"Creazione socket fallita\n");
exit(1);
}

if(connect(sd,(struct sockaddr *)&sad,sizeof(sad))<0){
fprintf(stderr,"Connessione fallita\n");
exit(1);
}

text=fgets(buf,sizeof(buf),stdin);

while(text!=NULL){
send(sd,buf,strlen(buf),0);
n=recv(sd,buf,sizeof(buf),0);
write(1,buf,n);
text=fgets(buf,sizeof(buf),stdin);
}

closesocket(sd);

exit(0);
}

T-Jack
18-04-2008, 11:36
Dunque, ho trovato almeno un paio di errori.
1.Quando nel server dichiari "char *buf[20]", il buffer non e' pulito. Devi inizializzarlo a zero con una memset altrimenti si inzozza tutto.

2. quando chiami fgets(), digiti a riga di comando "prova" e poi premi enter,
viene appesa una newline alla fine della stringa... e questo fa si' che la strcmp() non vada a buon fine.

xsatellitex
18-04-2008, 11:56
Ho provato cosi ma neanche funziona(riporto solo il finale modificato di server e client ):
------------------------------------Server:
while(1){
alen=sizeof(cad);

if((sd2=accept(sd,(struct sockaddr *)&cad,&alen))<0){
fprintf(stderr,"Accept failed\n");
exit(1);
}
printf("socket client sd %d\n",sd2);
memset(buf,0,sizeof(buf));
n=recv(sd2,buf,sizeof(buf),0);


while(n>0) {


if (strcmp(buf,"prova") == 0)
{ printf("ok");}
else{send(sd2,buf,n,0);}
memset(buf,0,sizeof(buf));
n=recv(sd2,buf,sizeof(buf),0);
}
closesocket(sd2);
}
}




---------------------------------------Client:

if(connect(sd,(struct sockaddr *)&sad,sizeof(sad))<0){
fprintf(stderr,"Connessione fallita\n");
exit(1);
}

//text=fgets(buf,sizeof(buf),stdin);

send(sd,"prova",5,0);
// while(text!=NULL){
// send(sd,buf,strlen(buf),0);
// n=recv(sd,buf,sizeof(buf),0);
// write(1,buf,n);
// text=fgets(buf,sizeof(buf),stdin);
// }

closesocket(sd);

exit(0);
}

:muro:

T-Jack
18-04-2008, 12:15
Ora propio non ti so dire, perche' a me va'...
comunque in "send(sd,"prova",5,0);" e piu' corretto aggiungere il terminatore NULL al parametro len, ma questo non cambierebbe le cose...

xsatellitex
18-04-2008, 12:25
adesso funziona :rolleyes:

quindi il problema era del client come avevi detto... ;)

Quindi cosa dovrei scrivere nel client al posto di :

text=fgets(buf,sizeof(buf),stdin);

while(text!=NULL){
send(sd,buf,strlen(buf),0);
n=recv(sd,buf,sizeof(buf),0);
write(1,buf,n);
text=fgets(buf,sizeof(buf),stdin);
}

ho provato a usare il memset ma non funziona... magari ci vuole qualche altra funzione al posto di fgets.

xsatellitex
18-04-2008, 12:45
Ho risolto con un banale scanf... grazie infinite per l'aiuto :D

T-Jack
18-04-2008, 12:46
:D Sono felice di averti aiutato... per quel poco che posso fare.
l'unico dilemma che devi affrontare adesso e quello dell'input...

fgets() include un newline alla fine dell'input, mentre gets() lo rimuove.
Tuttavia gets() apre le porte agli errori da overflow, e poi c'e scanf()...
Altrimenti usa follie del tipo:
*(buf+strlen(buf)-1) = 0;
dopo una chiamata a fgets()!