Salve a tutti, mi presento mi chiamo Francesco ed è la prima volta che scrivo su questo forum.Mi sono iscritto perchè sto avendo problemi relativi ad un programma in linguaggio c.
Passo alla spiegazione :
Il programma deve gestire ,tramite client-server, la gestione di una banca con tutte le operazioni descritte nel menù.
Una volta scritto e mandato in esecuzione il programma ho riscontrato 2 "difetti":
1) quando eseguo il client e passo il mio indirizzo ip della rete di casa il server che è in ascolto non trascrive il mio indirizzo esatto.Spiego meglio con un esempio: il mio indirizzo ip è 192.168.1.40 quindi quando eseguo ./client 192.168.1.40 il server come risposta mi dice che ha avuto una richiesta accettata dall'ip 0.0.0.0 sulla porta 0.
2) una volta scelto di terminare il client tramite l'azione del menù, il server rimane attivo.
Posto il codice di seguito
Client:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
//lista delle librerie
int n,codice,y,sockfd;
char recvline[1025] ;
typedef struct bancomat
{
char cognome[100];
char nome[100];
int codice_cliente;
int denaro_cliente;
}t_bancomat;
t_bancomat array_utenti[100];
t_bancomat ricevi;
int sockfd, n,a,i=0,scelta;
char recvline[1025] ;
char buff[4096];
struct sockaddr_in servaddr;
//----------------------PROTOTIPI---------------------------------
int ricerca_cliente();
int aggiungi_denaro(t_bancomat array_utente[],int y);
int prelievo_denaro(t_bancomat array_utente[],int y);
void stampa();
void riempi_array(t_bancomat array_utenti[]);
int trasferimento_denaro(t_bancomat array_utente[]);
//----------------------------------------------------------------
int main(int argc, char **argv)
{
if (argc != 2)
{
fprintf(stderr,"usage: %s <IPaddress>\n",argv[0]);
exit (1);
}
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr,"socket error\n");
exit (1);
}
//crep òa socket
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(3666);
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
{
fprintf(stderr,"inet_pton error for %s\n", argv[1]);
exit (1);
}
//do la definizione alla socket, la famiglia ip4, la porta associata e faccio la conversione
//della stringa che rappresenta l'indirizzo d rete
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
fprintf(stderr,"connect error\n");
exit(1);
}
//cerco di connettermi al server
while (1)
{
//stampo il menù
printf("Selezionare l'opzione desiderata\n");
printf("1) Ricerca cliente\n");
printf("2) Aggiungi denaro\n");
printf("3) Preleva denaro\n");
printf("4) Trasferisci denaro\n");
printf("5) Chiudi sistema\n");
scanf("%d",&scelta);
//leggo la scelta dell'utente e la invio al server tramite la write
snprintf(buff, sizeof(buff), "%d\r\n",scelta);
if ( write(sockfd, buff, strlen(buff)) != strlen(buff))
{
perror("write");
exit(1);
}
// lo switch mi indirizza verso la mia scelta e chiama la procedura associata
switch (scelta)
{
case 1:
i=ricerca_cliente();
stampa();
break;
case 2:
i=ricerca_cliente();
aggiungi_denaro(array_utenti,i);
stampa();
break;
case 3:
i=ricerca_cliente();
prelievo_denaro(array_utenti,i);
stampa();
break;
case 4:
i=ricerca_cliente();
y=trasferimento_denaro(array_utenti);
stampa();
break;
case 5:
exit(1);
break;
default:
printf("errore \n");
break;
}
}
exit(0);
}
int ricerca_cliente()
{
int i=0;
printf("Inserire il codice utente da ricercare \n");
scanf("%d",&codice);
snprintf(buff, sizeof(buff), "%d\r\n",codice);
if ( write(sockfd, buff, strlen(buff)) != strlen(buff))
{
perror("write");
exit(1);
}
//questa funzione chiede il codice utente da ricercare e lo invia al server tramite una write
}
int aggiungi_denaro(t_bancomat array_utente[],int y)
{
int i=0,aggiungi;
printf("quanto vuoi depositare? \n");
scanf("%d",&aggiungi);
snprintf(buff, sizeof(buff), "%d\r\n",aggiungi);
if ( write(sockfd, buff, strlen(buff)) != strlen(buff))
{
perror("write");
exit(1);
}
//questa funzione chiede all'utente quanto vuole depositare e tramite una write lo invia al server
}
int prelievo_denaro(t_bancomat array_utente[],int y)
{
int preleva;
printf("quanto vuoi prelevare? \n");
scanf("%d",&preleva);
snprintf(buff, sizeof(buff), "%d\r\n",preleva);
if ( write(sockfd, buff, strlen(buff)) != strlen(buff))
{
perror("write");
exit(1);
}
//questa funzione chiede all'utente quanto vuole prelevare e tramite una write lo invia al server
}
void stampa()
{
read(sockfd, &ricevi, sizeof(ricevi));
printf("cognome %s \n", ricevi.cognome);
printf("nome %s \n", ricevi.nome);
printf("denaro cliente €%d \n", ricevi.denaro_cliente);
printf("codice cliente n°%d \n", ricevi.codice_cliente);
//questa procedura riceve tramite la read i dati del cliente e li stampa con una printf
}
int trasferimento_denaro(t_bancomat array_utente[])
{
int i_mittente,somma,i_destinatario;
printf("A chi vuoi destinare il bonifico= ");
i_destinatario=ricerca_cliente(array_utente);
printf("quanto vuoi trasferire? ");
scanf("%d",&somma);
snprintf(buff, sizeof(buff), "%d\r\n",somma);
if ( write(sockfd, buff, strlen(buff)) != strlen(buff))
{
perror("write");
exit(1);
}
return(i_destinatario);
//questa funzione è per il trasferimento d denaro chiede per prima cosa i codici degli utenti, poi chiede la somma da trasferire e invia tutto al
//server che gestità i dati ricevuti
}
Server:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
//lista di librerie
typedef struct bancomat
{
char cognome[100];
char nome[100];
int codice_cliente;
int denaro_cliente;
}t_bancomat; // struct per la gestione dei dati
t_bancomat prova;
int socket_list, connfd,a,n,socket_conn;
struct sockaddr_in servaddr,client;
//char buffer[4096];
char recvline[1025];
time_t atime;
pid_t pid;
int n,codice,i=1,y;
int logging =0;
int one=1;
//----------------------PROTOTIPI---------------------------------
int ricerca_cliente(t_bancomat array_utenti[]);
int aggiungi_denaro(t_bancomat array_utente[],int y);
int prelievo_denaro(t_bancomat array_utente[],int y);
void stampa(t_bancomat array_utente[], int y);
void riempi_array(t_bancomat array_utenti[]);
int trasferimento_denaro(t_bancomat array_utente[]);
//----------------------------------------------------------------
int main(int argc, char **argv)
{
int scelta,z=0;
char buffer[4096];
t_bancomat array_utenti[100];
if (( socket_list = socket(AF_INET, SOCK_STREAM, 0) ) < 0 ) //creo la socket altrimenti stampa l'errore
{
perror("Creazione socket fallita!\n");
exit(1);
}
riempi_array(array_utenti); //carico i dati sull'array
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(3666);
//do la definizione alla socket, la famiglia ip4, la porta associata e faccio la conversione
//della stringa che rappresenta l'indirizzo d rete
if(setsockopt(socket_list, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))<0)
{
printf("ERROR_SETSOCKOPT\n");
exit(1);
}//setsockopt è una chiamata per la gestione degli errori
printf("Setsockopt riuscita\n");
if ( bind(socket_list, (struct sockaddr *) &servaddr,sizeof(servaddr)) < 0 )
{
perror("ERROR_BIND\n");
exit(1);
}printf("Bind riuscita\n");
// la bind assegna un'indirizzo
if ( listen(socket_list, 1024) < 0 )
{
perror("ERROR_LISTEN\n");
exit(1);
}printf("In ascolto...\n");
// la listen si mette in ascolto d eventuali connessioni da parte di un client
while(1)
{
if ( ( socket_conn = accept(socket_list, (struct sockaddr *) NULL, NULL) ) < 0 )
{
perror("ERROR_ACCEPT");
exit(1);
}else {
printf("Connessione Accettata\n");
logging=1;
}
//questa funzione accetta la connessione da parte di un client, notare che c'è un while prima
//in modo da poter gestire + connessioni contemporaneamente grazie anche alla funzione che segue
if((pid= fork())<0)
{
perror (" FORK ERROR");
exit ( -1);
}
if(pid==0)
{ // la fork() crea un processo figlio identico a quello del padre
close (socket_list);
if(logging)
{
inet_ntop(AF_INET,&client.sin_addr,buffer,sizeof(buffer));
printf("richiesta dell' host %s con porta %d\n",buffer,ntohs(client.sin_port));
}
while (1)
{
n = read(socket_conn, recvline, 1024);
recvline[n] = 0;
if (fputs(recvline, stdout) == EOF)
{
fprintf(stderr,"fputs error\n");
exit(1);
}
scelta=atoi(recvline);
// legge con una read la scelta fatta dal client e mandatagli tramite la socket
switch (scelta)
{
//lo switch gestisce le varie scelte in ogni caso fa prima la ricerca del client
case 1:
i=ricerca_cliente(array_utenti);
stampa(array_utenti,i);
break;
case 2:
i=ricerca_cliente(array_utenti);
aggiungi_denaro(array_utenti,i);
stampa(array_utenti,i);
break;
case 3:
i=ricerca_cliente(array_utenti);
prelievo_denaro(array_utenti,i);
stampa(array_utenti,i);
break;
case 4:
i=ricerca_cliente(array_utenti);
y=trasferimento_denaro(array_utenti);
stampa(array_utenti,y);
break;
case 5:
printf("Connessione Terminata..\n");
exit(1);
break;
default:
printf("errore \n");
exit(1);
break;
z=z++;
}
}
close(socket_conn);
}
close(socket_conn);
//chiude la connessione
}
exit(0);
}
void riempi_array(t_bancomat array_utenti[])
{
//funzione che riempe l'array di dati
strcpy(array_utenti[1].cognome, "Napolitano");
strcpy(array_utenti[1].nome, "Gennaro");
array_utenti[1].codice_cliente=1001;
array_utenti[1].denaro_cliente=5000;
strcpy(array_utenti[2].cognome,"Rossi");
strcpy(array_utenti[2].nome,"Mario");
array_utenti[2].codice_cliente=1002;
array_utenti[2].denaro_cliente=3700;
strcpy(array_utenti[3].cognome,"Bianco");
strcpy(array_utenti[3].nome,"Luigi");
array_utenti[3].codice_cliente=1003;
array_utenti[3].denaro_cliente=6600;
strcpy(array_utenti[4].cognome,"Verdi");
strcpy(array_utenti[4].nome,"Antonio");
array_utenti[4].codice_cliente=1004;
array_utenti[4].denaro_cliente=900;
}
int ricerca_cliente(t_bancomat array_utenti[])
{
//funzione che ricerca il cliente dopo aver letto tramite la read il codice inviato dal client e restituisce l'indice dell'utente ricercato
int i=0,n,codice;
printf("Inserire il codice utente da ricercare \n");
n = read(socket_conn, recvline, 1024);
recvline[n] = 0;
if (fputs(recvline, stdout) == EOF) {
fprintf(stderr,"fputs error\n");
exit(1);
}
codice=atoi(recvline);
printf("codice %d\n",codice);
while(array_utenti[i].codice_cliente!=codice)
{
i++;
}
return(i);
}
int aggiungi_denaro(t_bancomat array_utente[],int y)
{
//funzione che "aggiunge denaro", dopo aver ricevuto il codice dell'utente del quale bisogna aggiungere denaro, legge tramite
//socket la somma da aggiungere
int aggiungi,n;
n = read(socket_conn, recvline, 1024);
recvline[n] = 0;
if (fputs(recvline, stdout) == EOF) {
fprintf(stderr,"fputs error\n");
exit(1);
}
aggiungi=atoi(recvline);
printf("prima %d\n",array_utente[y].denaro_cliente);
array_utente[y].denaro_cliente=array_utente[y].denaro_cliente+aggiungi;
printf("dopo %d\n",array_utente[y].denaro_cliente);
}
int prelievo_denaro(t_bancomat array_utente[],int y)
{
//funzione che "preleva denaro", dopo aver ricevuto il codice dell'utente del quale bisogna prelevare denaro, legge tramite
//socket la somma da prelevare
int preleva,n;
n = read(socket_conn, recvline, 1024);
recvline[n] = 0;
if (fputs(recvline, stdout) == EOF) {
fprintf(stderr,"fputs error\n");
exit(1);
}
preleva=atoi(recvline);
printf("prima %d\n",array_utente[y].denaro_cliente);
array_utente[y].denaro_cliente=array_utente[y].denaro_cliente-preleva;
printf("dopo %d\n",array_utente[y].denaro_cliente);
}
void stampa(t_bancomat array_utente[], int y)
{
//procedura che invia al client la struct contenente i dati del cliente della banca
prova=array_utente[y];
write(socket_conn,&prova,sizeof(prova));
}
int trasferimento_denaro(t_bancomat array_utente[])
{
//funzione che permette il trasferimento di denaro tra un'utente e un'altro. prima riceve i due codici degli utenti e poi trasferisce
//la somma da un'utente ad un'altro
int i_mittente,somma,i_destinatario,n;
i_destinatario=ricerca_cliente(array_utente);
n = read(socket_conn, recvline, 1024);
recvline[n] = 0;
if (fputs(recvline, stdout) == EOF) {
fprintf(stderr,"fputs error\n");
exit(1);
}
somma=atoi(recvline);
printf("codice destinatario %d",i_destinatario);
array_utente[i].denaro_cliente=array_utente[i].denaro_cliente-somma;
array_utente[i_destinatario].denaro_cliente=array_utente[i_destinatario].denaro_cliente+somma;
return(i_destinatario);
}
I problemi sono nel server penso per quanto riguarda il primo problema, credo nella chiamata
inet_ntop(AF_INET,&client.sin_addr,buffer,sizeof(buffer));
printf("richiesta dell' host %s con porta %d\n",buffer,ntohs(client.sin_port));
Vi ringrazio in anticipo per l'aiuto!