PDA

Visualizza la versione completa : [C]problema lettura stringa client/server


and77
25-09-2010, 19:13
Salve,
sto facendo delle esercitazioni con le applicazioni client/server.Il problema che si presenta in questo caso è che il server non legge la stringa inviata dal client.La stringa l'ho inserita all'interno di una struttura.



server:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/wait.h>
#include <signal.h>
#define LIST_PORT 50600
#define BACKLOG 100
struct dati{
char string[100];
size_t len;
};

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

struct sockaddr_in serv_add,cli_add;
char addr[INET_ADDRSTRLEN];
size_t len;
int conn_fd,list_fd,pid;

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

memset((void*)&serv_add,0,sizeof(serv_add));
serv_add.sin_family=AF_INET;
serv_add.sin_port=htons(LIST_PORT);
serv_add.sin_addr.s_addr=htonl(INADDR_ANY);

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

/*rilascio privilegi amministratore*/
if( setgid(65534) != 0){
perror("setuid() error");
exit(1);
}

if( setuid(65534) != 0){
perror("setgid() error");
exit(1);
}

if( listen(list_fd,BACKLOG) < 0){
perror("listen() error");
exit(1);
}
while(1){
len=sizeof(cli_add);
while( (conn_fd=accept(list_fd,(struct sockaddr*)&cli_add,&len) <= 0) && (errno==EINTR))
;

if( inet_ntop(AF_INET,&cli_add.sin_addr,addr,INET_ADDRSTRLEN*sizeof(char) ) == NULL){
perror("inet_ntop() error");
exit(1);
}

printf("client address %s client port %d\n",addr,ntohs(cli_add.sin_port));

pid=fork();

if( pid < 0 ){
perror("fork() error");
exit(1);
}
else{

if( pid == 0){ //processo figlio
printf("PROCESSO FIGLIO\n");
//char string[100];
struct dati data;
ssize_t nread;
ssize_t byte;

memset((void*)&data,0,sizeof(data));
printf("1 string %s\n",data.string);
close(list_fd);

if( (nread=read(conn_fd,&data,sizeof(data))) < 0){
perror("read() error");
exit(1);
}
printf("sono qui\n");
data.string[nread]='\0';
printf("nread %d\n",nread);
fputs(data.string,stdout);
/* if( feof(stdout) == 0 ){
perror("fputs() error");
exit(1);
}*/

printf("sono qui\n");
printf("string %s\n",data.string);

printf("nread %d\n",nread);
if( nread < 0){
perror("read() error");
exit(1);
}
exit(0);
}
/*else{
printf("processo padre\n");

waitpid(pid,NULL,WNOHANG);
printf("uscita processo padre\n");


}*/
}
}
}

void handler_child(int signo){
int pid;
printf("catching SIG_CHLD signal\n");
while(pid=waitpid(WAIT_ANY,NULL,WNOHANG) != 0)
;

}

client

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <errno.h>
#define LIST_PORT 50600
struct dati{
char string[100];
size_t len;
};

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

struct sockaddr_in serv_add;
int conn_fd;char string[100];
ssize_t nwritten;

struct dati data;




if( argc != 2){
fprintf(stdout,"USO:%s <indirizzo server>\n",argv[0]);
exit(1);
}


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

memset((void*)&serv_add,0,sizeof(serv_add));

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

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

if( (connect(conn_fd,(struct sockaddr*)&serv_add,sizeof(serv_add))) <0){
perror("connection error");
exit(1);
}
sprintf(data.string,"Client PID %d\r\n",getpid());
data.len=strlen(data.string);
printf("string %s lunghezza %d\n",data.string,data.len);

/*if( (FullWrite(conn_fd,string,sizeof(char)*strlen(stri ng))) < 0){
fprintf(stderr,"error FullWrite()");
exit(1);
}*/
if( write(conn_fd,&data,sizeof(data)) != sizeof(data)){
perror("2 write() error");
exit(1);
}
}

int FullWrite(int fd,void *buf,size_t byte){

size_t nleft=byte;
ssize_t nwritten;

while(nleft > 0){
if( (nwritten=write(fd,buf,nleft)) < 0){
if( errno == EINTR){
continue;
}
else{
return(nwritten);
}
}
nleft-=nwritten;
buf+=nwritten;
}
return(nleft);
}


Non riesco a capire dove sbaglio.Grazie per i consigli.

YuYevon
25-09-2010, 21:13
Qualcosa di molto simile a quello che si è visto qualche tempo fa su questo forum proprio in un'applicazione Unix client/server... consiglio di compilare *sempre* con opzioni più restrittive, in particolare -Wall.

Questa riga nel server



while( (conn_fd=accept(list_fd,(struct sockaddr*)&cli_add,&len) <= 0) && (errno==EINTR))


considerando solo la prima condizione, significa "a conn_fd assegna il valore di accept(...) <= 0", quindi conn_fd varrà 0 o 1 a seconda del fatto che il valore restituito dalla accept() sia o non sia <= 0.



while( (conn_fd=accept(list_fd,(struct sockaddr*)&cli_add,&len)) <= 0 && (errno==EINTR))


non ho controllato bene tutto l'output e tutto il codice, ma in questo modo il server riceve la stringa e la stampa. Consiglio anche di includere gli header file unistd.h e fcntl.h che mancano in entrambi i codici, pur essendo necessari.

and77
25-09-2010, 22:14
Ok,
perfetto.Grazie.

Loading