Salve raga, è la mia prima visita su questo forum, ho un problema sul quale sbatto la testa da giorni, spiego brevemente l'esempio che poi vi posterò, devo creare un server ed un client che interagiscono per creare alla fine un elenco "telefonico" ,il mio problema è che le informazioni che passo da terminale vengono ricopiate su file di testo in maniera del tutto mal formattata e con aggiunta di caratteri a caso, spero che magari qualcuno sia disposto ad aiutarmi ,ci combatto da giorni ma non riesco a capire dove sia il problema.
Vi posto il codice da me prodotto. Questo è il client:
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/signal.h>
#include <errno.h>
#define perror(x) {puts(x); exit(1);}
void gest_broken_pipe(){
perror("Il Server si è disconnesso");
}
void gest_interruzione(){
perror("Interruzione improvvisa del processo");
}
// Funzione per stampare il menu iniziale
void menu(void){
printf("MENU INIZIALE\n\n");
printf("\t1) Aggiungi nuovo contatto\n");
printf("\t2) Trova contatto\n");
printf("\t3) Esci\n");
printf("\t0) Shutdown del Server\n");
}
int scelta(){
int comando;
menu();
puts("Inserisci l'operazione da effettuare: ");
scanf("%d", &comando);
while(comando<0 || comando>3){
puts("Operazione sconosciuta, riprovare: ");
menu();
scanf("%d", &comando);
}
return comando;
}
int passwordCorretta(int ds_sock){
char password[10];
char risPassword[2];
char risposta[3];
printf("Inserire la password >> ");
scanf("%s", password);
if(write(ds_sock, password, sizeof(password))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(strcmp(password,"0")==0){
printf("Sei sicuro di voler tornare al menu iniziale? [SI/NO]\n");
scanf("%s", risposta);
if(write(ds_sock, risposta, sizeof(risposta))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(strcmp(risposta,"SI")==0) return 0;
}
if(read(ds_sock,risPassword, sizeof(risPassword))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
while(strcmp(risPassword,"0")==0){
printf("CLIENT: password errata, riprovare.\n");
printf("Inserire la password >> ");
scanf("%s", password);
if(write(ds_sock, password, sizeof(password))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(strcmp(password,"0")==0){
printf("Sei sicuro di voler tornare al menu iniziale? [SI/NO]\n");
scanf("%s", risposta);
if(write(ds_sock, risposta, sizeof(risposta))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(strcmp(risposta,"SI")==0) return 0;
}
if(read(ds_sock, risPassword, sizeof(risPassword))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
}
return 1;
}
void main(){
int ds_sock, length, res;
struct sockaddr_in client;
struct hostent *hp;
char oper[2];
int risPwd;
int op;
char cognome[30];
char nome[20];
char telefono[12];
char continua[3];
char ris[2];
int trovato;
int aggiunto;
ds_sock = socket(AF_INET, SOCK_STREAM, 0);
client.sin_family = AF_INET;
client.sin_port = 1999;
hp = gethostbyname("localhost"); //indirizzo del server
memcpy(&client.sin_addr, hp->h_addr, 4);
res = connect(ds_sock, &client, sizeof(client));
if(res==-1) {
perror("Errore nella connessione");
}
signal(SIGPIPE, gest_broken_pipe);
signal(SIGINT, gest_interruzione);
do{
op=scelta();
sprintf(oper,"%d",op);
if(write(ds_sock, oper, sizeof(oper))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
switch(op){
case 1:
printf("INSERIMENTO NUOVO CONTATTO\n");
if(passwordCorretta(ds_sock)){
printf("CLIENT: password aggiungi corretta\n");
do{ ////////////////////////////////////////////////////////////////////////////////////////
printf("Cognome >> \n");
scanf("%s", cognome);
printf("Nome >> \n");
scanf("%s", nome);
printf("Telefono >> \n");
scanf("%s", telefono);
if(write(ds_sock, cognome, sizeof(cognome))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(write(ds_sock, nome, sizeof(nome))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(write(ds_sock, telefono, sizeof(telefono))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(read(ds_sock, ris, sizeof(ris))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
trovato=atoi(ris);
switch(trovato){
case 0:
printf("Errore di lettura nel Server\n");
break;
case 1:
printf("Il contatto è già presente nell'elenco\n");
break;
case 2:
if(read(ds_sock, ris, sizeof(ris))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
aggiunto=atoi(ris);
if(aggiunto==0) printf("Errore di scrittura nel Server\n");
else printf("Il contatto è stato correttamente inserito nell'elenco\n");
break;
}
printf("Vuoi aggiungere un altro contatto? [SI/NO]\n");
scanf("%s", continua);
if(write(ds_sock, continua, sizeof(continua))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
}while(strcmp(continua, "SI")==0);
}
break;
case 2:
printf("RICERCA DI UN NUMERO TELEFONICO\n");
if(passwordCorretta(ds_sock)){
printf("CLIENT: password cerca corretta\n");
do{
printf("Cognome >> ");
scanf("%s", cognome);
printf("Nome >> ");
scanf("%s", nome);
if(write(ds_sock, cognome, sizeof(cognome))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(write(ds_sock, nome, sizeof(nome))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(read(ds_sock, ris, sizeof(ris))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
trovato=atoi(ris);
switch(trovato){
case 0:
printf("Errore di lettura nel Server\n");
break;
case 1:
if(read(ds_sock, telefono, sizeof(telefono))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
if(strcmp(telefono, "errore")==0) printf("Errore di lettura nel Server\n");
else printf("Il telefono del contatto richiesto è: %s\n", telefono);
break;
case 2:
printf("Il contatto non è presente nell'elenco\n");
break;
}
printf("Vuoi cercare un altro numero di telefono? [SI/NO]\n");
scanf("%s", continua);
if(write(ds_sock, continua, sizeof(continua))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
}while(strcmp(continua, "SI")==0);
}
break;
case 3:
printf("USCITA\n");
break;
case 0:
printf("Eseguito lo SHUTDOWN del Server\n");
break;
}
}while(op!=3 && op!=0);
close(ds_sock);
}
Questo è il Server:
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/sem.h>
#include <sys/signal.h>
#include <errno.h>
#define perror(x) {puts(x); exit(1);}
#define MAX_CODA 10
typedef struct contatto{
char cognome[30];
char nome[20];
char telefono[12];
}contatto;
int scr, nlett; //identificatori semafori
int key_scr = 40; //chiavi semafori
int key_nlett = 50;
int ds_file; //descrittore del file
int ds_sock; //descrittore del socket
void gest_broken_pipe(){
perror("Un client si è disconnesso");
}
void gest_interruzione(){
perror("Interruzione improvvisa del processo");
}
int passwordCorretta(int ds_sock, int op){
char password[10];
char risposta[3]; // SI\NO
char risPassword[2];
int risPwd;
char Pwd[10]; //password effettiva, da confrontare
if(op==1) strcpy(Pwd,"1234");
else strcpy(Pwd,"5678");
if(read(ds_sock, password, sizeof(password))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(strcmp(password,"0")==0){
//sei sicuro di voler uscire? (torna al menu iniziale)
if(read(ds_sock, risposta, sizeof(risposta))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
if(strcmp(risposta,"SI")==0) return 0;
}
while(strcmp(password,Pwd)!=0){
//password errata
risPwd=0;
sprintf(risPassword,"%d",risPwd);
if(write(ds_sock, risPassword, sizeof(risPassword))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(read(ds_sock, password, sizeof(password))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
if(strcmp(password,"0")==0){
//sei sicuro di voler uscire? (torna al menu iniziale)
if(read(ds_sock, risposta, sizeof(risposta))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
if(strcmp(risposta,"SI")==0) return 0; //l'utente vuole tornare al menu principale
}
}
if(strcmp(password,Pwd)==0){
risPwd=1;
sprintf(risPassword,"%d",risPwd);
if(write(ds_sock, risPassword, sizeof(risPassword))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
}
return 1; //password corretta
}
int semWait(int id_sem){
struct sembuf swait = {0,-1,0};
return semop(id_sem, &swait, 1);
}
int semSignal(int id_sem){
struct sembuf ssignal = {0,1,0};
return semop(id_sem, &ssignal, 1);
}
int semWaitZero(int id_sem){
struct sembuf swaitzero = {0,0,0};
return semop(id_sem, &swaitzero, 1);
}
int cerca(contatto a, int df){
int sizeRD;
contatto z;
lseek(df,0,0);
do{
sizeRD=read(df, z.cognome, sizeof(z.cognome));
if(sizeRD==-1) return 0;
sizeRD=read(df, z.nome, sizeof(z.nome));
if(sizeRD==-1) return 0;
lseek(df,sizeof(z.telefono),1);
if(strcmp(a.cognome,z.cognome)==0 && strcmp(a.nome,z.nome)==0) return 1; //contatto presente
}while(sizeRD>0);
return 2; //contatto non presente
}
int aggiungi(contatto a, int df){
int sizeWR;
lseek(df,0,2);
sizeWR=write(df, a.cognome, sizeof(a.cognome));
if(sizeWR==-1) return 0;
sizeWR=write(df, a.nome, sizeof(a.nome));
if(sizeWR==-1) return 0;
sizeWR=write(df, a.telefono, sizeof(a.telefono));
if(sizeWR==-1) return 0;
return 1; //contatto aggiunto correttamente
}
void gestoreOperazioni(int ds_sock_a, int ds_file_a, int pidpadre){
char oper[2];
int op;
char continua[3];
contatto a;
int trovato;
int aggiunto;
char ris[2];
int size;
char telefono[12];
signal(SIGPIPE, gest_broken_pipe);
signal(SIGINT, gest_interruzione);
do {
if(read(ds_sock_a, oper, sizeof(oper))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
op=atoi(oper);
switch(op){
case 1:
if(passwordCorretta(ds_sock_a, op)){
do{
if(read(ds_sock_a, a.cognome, sizeof(a.cognome))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
if(read(ds_sock_a, a.nome, sizeof(a.nome))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
if(read(ds_sock_a, a.telefono, sizeof(a.telefono))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
semWait(scr);
semWaitZero(nlett);
/*------INSERIMENTO------------------------*/
trovato=cerca(a,ds_file_a);
sprintf(ris,"%d",trovato);
if(write(ds_sock_a, ris, sizeof(ris))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(trovato==2){
aggiunto=aggiungi(a,ds_file_a);
sprintf(ris,"%d",trovato);
if(write(ds_sock_a, ris, sizeof(ris))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
}
/*----------------------------------------*/
semSignal(scr);
//Vuoi aggiungere un altro contatto?
if(read(ds_sock_a, continua, sizeof(continua))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
}while(strcmp(continua, "SI")==0);
}
break;
case 2:
if(passwordCorretta(ds_sock_a, op)){
do{
if(read(ds_sock_a, a.cognome, sizeof(a.cognome))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
if(read(ds_sock_a, a.nome, sizeof(a.nome))<0){
if(errno!=EINTR) perror("Errore di lettura");
}
semWait(scr);
semSignal(nlett);
semSignal(scr);
/*------RICERCA---------------------------*/
trovato=cerca(a,ds_file_a);
sprintf(ris,"%d",trovato);
if(write(ds_sock_a, ris, sizeof(ris))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
if(trovato==1){
lseek(ds_file_a,-sizeof(telefono),1);
size=read(ds_file_a, telefono, sizeof(telefono));
if(size==-1) strcpy(telefono,"errore");
if(write(ds_sock_a, telefono, sizeof(telefono))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
}
/*----------------------------------------*/
semWait(nlett);
//Vuoi cercare un altro numero di telefono?
if(read(ds_sock_a, continua, sizeof(continua))<0){
if(errno!=EINTR) perror("Errore di scrittura");
}
}while(strcmp(continua, "SI")==0);
}
break;
case 0:
kill(pidpadre, SIGTERM);
exit(0);
break; //questa istruzione non viene mai raggiunta
}
}while(op!=3);
close(ds_sock_a);
close(ds_file_a);
}
void fine(){
printf("SHUTDOWN del Server in corso (chiusura delle risorse)\n");
close(ds_file);
close(ds_sock);
semctl(scr,0,IPC_RMID,1);
semctl(nlett,0,IPC_RMID,1);
printf("SHUTDOWN del Server completato!\n");
exit(0);
}
void main(){
int ds_sock_a;
int length;
struct sockaddr_in server;
struct sockaddr client;
int ds_file_a;
int ret;
int my_pid=getpid();
//Creazione\apertura del file "elenco"
ds_file = open("elenco",O_RDWR|O_CREAT, 0666);
if (ds_file==-1) {
perror("Errore nell'apertura del file");
}
//Creazione dei semafori
scr = semget(key_scr, 1, IPC_CREAT|0666);
if (scr==-1) {
perror("Errore nella creazione del semaforo scr");
}
nlett = semget(key_nlett, 1, IPC_CREAT|0666);
if (nlett==-1) {
perror("Errore nella creazione del semaforo nlett");
}
//Inizializzazione dei semafori
ret = semctl(scr, 0, SETVAL, 1);
if (ret==-1) {
perror("Errore nell'inizializzazione del semaforo scr");
}
ret = semctl(nlett, 0, SETVAL, 0);
if (ret==-1) {
perror("Errore nell'inizializzazione del semaforo nlett");
}
//Creazione del socket
ds_sock = socket(AF_INET, SOCK_STREAM, 0);
server.sin_family = AF_INET;
server.sin_port = 1999;
server.sin_addr.s_addr = INADDR_ANY;
//Assegnazione dell'indirizzo
bind(ds_sock, &server, sizeof(server));
listen(ds_sock, MAX_CODA);
length = sizeof(client);
signal(SIGCHLD, SIG_IGN);
signal(SIGTERM, fine);
while(1) {
//Attesa connessioni entranti
while((ds_sock_a = accept(ds_sock, &client, &length)) == -1);
ds_file_a = dup(ds_file);
if(fork()==0) {
gestoreOperazioni(ds_sock_a, ds_file_a, my_pid);
}
else{
close(ds_sock_a);
}
}
}
Vi ho postato tutto il malloppo per farvi avere una idea chiarissima della situazione, se avete problemi a capire qualcosa chiedete pure.
Grazie a tutti per l'eventuale aiuto.