Rieccomi, ma stavolta con un po' di codice già scritto... funzionante, ma per niente soddisfacente.
Potreste consigliarmi qualche modifica?
Posto il codice:
/**
Server Management
*/
#include <stdio.h>
#include <stdlib.h> //exit
#include <string.h> //strlen
#include <time.h> //time
#include <unistd.h> //read,write,close
#include <sys/types.h> //socket,bind,listen,connect
#include <sys/socket.h> //socket,bind,listen,connect
#include <arpa/inet.h> //struct sockaddr_in
typedef struct Mul{
int id;
int disponibile; //0 libero 1 occupato
}Muletti;
typedef struct Scaf{
int id;
int coord_x;
int coord_y;
}Scaffali;
int main(int argc,char *argv[])
{
int nread, nwrite;
int listenAfd,connAfd; //usiamo due descrittori perchè ci accetta sulla listenfd e si passa a connfd su cui si porta avanti il servizio. Quindi il primo accetta la connessione, mentre il servizio viene svolto dal secondo
int listenMfd,connMfd;
struct sockaddr_in clientMuletaddr;
struct sockaddr_in clientAdminaddr;
int logging = 0;
char buffer[10];
socklen_t len;
pid_t pid;
int conferma = 0;
int i=-1,j=0;
int ordine;
//struct muletti
Muletti muletti[4];
/////////////////////////////
// INIZIALIZZARE L'ARRAY DAI MULETTI INSERENDO LA DISPONIBILITÀ DI OGNUNO A UN 3° STATO
muletti[4]={2,2,2,2};
////////////////////////////
//struct scaffali
Scaffali scaffale[4];
/*CONNESSIONE MULETTI LIBERI*/
if ((listenMfd = socket(AF_INET, SOCK_STREAM, 0) ) < 0 )
{
perror("socket");
exit(1);
}
printf("1\n");
/* clear server address */
memset((void *)&clientMuletaddr, 0, sizeof(clientMuletaddr));
clientMuletaddr.sin_family = AF_INET;
clientMuletaddr.sin_port = htons(35951); //porta su cui sono in ascolto
clientMuletaddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY: il server può ricevere richieste da qualsiasi clientMuletaddr nella rete
/* richiedo al SO di collegare il socket alla porta che ho richiesto */
if (bind(listenMfd, (struct sockaddr *) &clientMuletaddr, sizeof(clientMuletaddr)) < 0 )
{
perror("bind");
exit(1);
}
printf("2\n");
/* mette il socket in modalità ascolto */
if(listen(listenMfd, 4) < 0 ) //1024: lunghezza della coda di attesa (NON LA LUNGHEZZA MASSIMA) dei clientMuletaddr che vogliono connettersi al server
{
perror("Listen error\n");
exit(1);
}
printf("3\n");
/*CONNESSIONE ADMIN*/
if ((listenAfd = socket(AF_INET, SOCK_STREAM, 0) ) < 0 )
{
perror("socket");
exit(1);
}
printf("1.1\n");
/* clear server address */
memset((void *)&clientAdminaddr, 0, sizeof(clientAdminaddr));
clientAdminaddr.sin_family = AF_INET;
clientAdminaddr.sin_port = htons(35952); //porta su cui sono in ascolto
clientAdminaddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY: il server può ricevere richieste da qualsiasi clientAdminaddr nella rete
/* richiedo al SO di collegare il socket alla porta che ho richiesto */
if (bind(listenAfd, (struct sockaddr *) &clientAdminaddr, sizeof(clientAdminaddr)) < 0 )
{
perror("bind");
exit(1);
}
printf("2.1\n");
/* mette il socket in modalità ascolto */
if(listen(listenAfd, 3) < 0 ) //1024: lunghezza della coda di attesa (NON LA LUNGHEZZA MASSIMA) dei clientAdminaddr che vogliono connettersi al server
{
perror("Listen error\n");
exit(1);
}
printf("3.1\n");
while (1)
{
i++;
len = sizeof(clientMuletaddr);
//accetta connessione muletto
if ( (connMfd = accept(listenMfd, (struct sockaddr *)&clientMuletaddr, &len)) <0 )
{
perror("accept error");
exit(-1);
}
printf("4\n");
/* fork to handle connection */
if ( (pid = fork()) < 0 )
{
perror("fork error");
exit(-1);
}
printf("5\n");
if (pid == 0)
{ /* child */
close(listenMfd);
logging=1;
if (logging)
{
printf("6\n");
// Converte l'indirizzo dalla relativa struttura in una stringa simbolica
inet_ntop(AF_INET, &clientMuletaddr.sin_addr, buffer, sizeof(buffer));
muletti[i].id = i;
if(i < 4)
{
printf(" Il client-muletto ha id : %d\n", muletti[i].id);
//invia a muletto il suo id
if(nwrite = write(connMfd,(void *) &muletti[i].id,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
//muletto gli comunica che è disponibile
if(nread = read(connMfd,(void *) &muletti[i].disponibile,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
printf("7\n");
if(muletti[i].disponibile == 0)
{
printf("8\n");
printf("Client muletto con id %d è libero\n", muletti[i].id);
//successivamente comunica a client admin id muletto libero e imposta disponibile a 1;
}
}else
{
printf("Non ci sono muletti disponibili al momento\n");
}
/*CONNESSIONE ADMIN*/
len = sizeof(clientAdminaddr);
//accetto connessione da admin
if ( (connAfd = accept(listenAfd, (struct sockaddr *)&clientAdminaddr, &len)) <0 )
{
perror("accept error");
exit(-1);
}
printf("4.1\n");
/* fork to handle connection */
if ( (pid = fork()) < 0 )
{
perror("fork error");
exit(-1);
}
printf("5.1\n");
if (pid == 0)
{ /* child */
close(listenAfd);
logging=1;
if (logging)
{
printf("6.1\n");
// Converte l'indirizzo dalla relativa struttura in una stringa simbolica
inet_ntop(AF_INET, &clientAdminaddr.sin_addr, buffer, sizeof(buffer));
//ricevo richiesta muletto libero
if(nread = read(connAfd,(void *) &muletti[i].id,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
muletti[i].id = i;
if(muletti[i].id == i && muletti[i].disponibile == 0)
{
printf(" Il client-muletto con id : %d e' disponibile\n", muletti[i].id );
//invio a admin id muletto
if(nwrite = write(connAfd,(void *) &muletti[i].id,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
//la disponibilità di muletto diventa occupata
muletti[i].disponibile = 1;
if(nwrite = write(connMfd,(void *) &muletti[i].disponibile,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
}else{
printf(" Tutti i client muletto sono occupati\n");
}
// PROTOTIPO SCELTA SCAFFALE
scaffale[j].id=j;
if(nread = read(connMfd,(void *) &ordine,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
if(ordine == 1 || ordine == 2)
{
printf("Server riceve richiesta da muletto per la posizione dello scaffale num° %d\n",j);
if(nread = read(connMfd,(void *) &scaffale[j].coord_x,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
if(nread = read(connMfd,(void *) &scaffale[j].coord_y,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
scaffale[j].coord_x = rand()%10;
printf("Coordinate x = &d ", scaffale[j].coord_x);
scaffale[j].coord_y = rand()%10;
printf("Coordinate y = &d ", scaffale[j].coord_y);
if(nwrite = write(connMfd,(void *) &j,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
if(nwrite = write(connMfd,(void *) &scaffale[j].coord_x,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
if(nwrite = write(connMfd,(void *) &scaffale[j].coord_y,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
if(nread = read(connAfd,(void *) &conferma,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
printf("conferma = %d\n",conferma);
if(conferma == 1)
{
printf("Operazione avvenuta con successo dal muletto\n");
}
j++;
}else if(ordine == 3)
{
printf("Au revoir!\n");
close(connMfd);
close(connMfd);
break;
}else
{
printf("Operazione non consentita\n");
}
}//chiusura logging 2
close(connAfd);
exit(0);
}//chiusura pid admin
else { /* parent */
close(connAfd);
}
}//chiusura logging 1
close(connMfd);
exit(0);
}// chiusura pid muletto
else { /* parent */
close(connMfd);
}
}//fine del while
/* normal exit, never reached */
exit(0);
}
/**
Client Muletto
*/
#include <stdio.h>
#include <stdlib.h> //exit
#include <unistd.h> //read, sleep
#include <sys/types.h> //socket,connect
#include <sys/socket.h> //socketconnect
#include <arpa/inet.h> //struct sockaddr_in
#include <string.h> /* memset */
typedef struct
{
int id;
int disponibile; //0 libero 1 occupato
}Muletti;
typedef struct
{
int id;
int coord_x;
int coord_y;
}Scaffali;
int main(int argc,char *argv[])
{
int nread, nwrite;
int sockfd;
struct sockaddr_in servaddr;
int porta=1000;
int ordine;
char conferma = 1;
int i=-1,j=0,k=0;
struct sockaddr_in clientMuletaddr;
struct sockaddr_in clientAdminaddr;
int listenMfd,connMfd;
int listenAfd,connAfd;
int seconds = 0;
socklen_t len;
//struct muletti
Muletti muletti[4];
muletti[4]={2,2,2,2};
//struct scaffali
Scaffali scaffale;
// controllo sugli argomenti
if (argc != 2) {
fprintf(stderr,"usage: %s <IPaddress>\n",argv[0]);
exit (1);
}
printf("1\n");
/*
1 paramentro famiglia di protocolli di rete
2 paramentro canale di comunicazione tcp
3 parametro non analizzato perchè i primi due specificano il protocollo utilizzato
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr,"socket error\n");
exit (1);
}
printf("2\n");
/*
Devo specificare i parametri della connessione
La struttura di base che vale per tutti i protocolli è sockaddr.
In particolare, noi usiamo sockaddr_in.
Primo paramentro: famiglia
Secondo: porta
Terzo: IP address che è un altra struttura (stringa di 32 bit)
*/
servaddr.sin_family = AF_INET;
printf("3\n");
/*
La porta su cui è in attesa il server.. htons è una funzione per la
conversione host to network in formato big endian per la rete
(s e l finale indicano short e long)
Fra gli indirizi internet utilizzabili nel campo "sin_addr" (definiti in "netinet/in.h")
ci sono "INADDR_ANY" (vengono accettati dati da qualunque parte vengano),
"INADDR_BROADCAST" (per mandare dati a tutti gli host),
"INADDR_LOOPBACK" (loopback sull'host locale).
*/
servaddr.sin_port = htons(35951);
printf("4\n");
/*
Indirizzo ip del server con cui devo andarmi a collegare.
*/
//Converte l'indirizzo espresso tramite una stringa nel valore numerico.
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0)
{
fprintf(stderr,"inet_pton error for %s\n", argv[1]);
exit (1);
}
printf("5\n");
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
fprintf(stderr,"connect error\n");
exit(1);
}
i++;
if(i==4)
{
exit(0);
}
muletti[i].disponibile = 0;
//riceve il suo id da server
if(nread = read(sockfd,(void *) &muletti[i].id,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
printf("Sono muletto con id %d e sono libero\n", muletti[i].id);
//invia la sua disponibilità
if(nwrite = write(sockfd,(void *) &muletti[i].disponibile,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
if(nread = read(sockfd,(void *) &muletti[i].disponibile,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
if(muletti[i].disponibile == 1)
printf("Sono muletto con id %d e sono occupato\n", muletti[i].id);
/*CONNESSIONE ADMIN*/
if ((listenAfd = socket(AF_INET, SOCK_STREAM, 0) ) < 0 )
{
perror("socket");
exit(1);
}
printf("1.1\n");
memset((void *)&clientAdminaddr, 0, sizeof(clientAdminaddr));
clientAdminaddr.sin_family = AF_INET;
clientAdminaddr.sin_port = htons(35953+muletti[i].id); //porta su cui sono in ascolto
clientAdminaddr.sin_addr.s_addr = htonl(INADDR_ANY); //INADDR_ANY: il server può ricevere richieste da qualsiasi clientAdminaddr nella rete
/* richiedo al SO di collegare il socket alla porta che ho richiesto */
if (bind(listenAfd, (struct sockaddr *) &clientAdminaddr, sizeof(clientAdminaddr)) < 0 )
{
perror("bind");
exit(1);
}
printf("2.1\n");
/* mette il socket in modalità ascolto */
if(listen(listenAfd, 4) < 0 ) //1024: lunghezza della coda di attesa (NON LA LUNGHEZZA MASSIMA) dei clientAdminaddr che vogliono connettersi al server
{
perror("Listen error\n");
exit(1);
}
printf("3.1\n");
while (1)
{
len = sizeof(clientMuletaddr);
if ( (connAfd = accept(listenAfd, (struct sockaddr *)&clientAdminaddr, &len)) <0 )
{
perror("accept error");
exit(-1);
}
if(nread = read(connAfd,(void *) &ordine,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
if(ordine == 1 || ordine == 2)
{
//invia ordine anche a management
if(nwrite = write(sockfd,(void *) &ordine,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
printf("Client muletto contatta Management circa la posizione dello scaffale su cui prelevare\n");
printf("1\n");
if(nwrite = write(sockfd,(void *) &scaffale.coord_x,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
printf("2\n");
if(nwrite = write(sockfd,(void *) &scaffale.coord_y,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
printf("3\n");
if(nread = read(sockfd,(void *) &scaffale.coord_x,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
printf("4\n");
if(nread = read(sockfd,(void *) &scaffale.coord_y,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
printf("Attendere completamento operazione (circa 30 secondi)\n");
do{
printf(".");
sleep(1); //simulo il lavoro del muletto
seconds++;
}while(seconds<30);
printf("Lavoro svolto con successo!!\n");
if(nwrite = write(connAfd,(void *) &conferma,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
}else if(ordine == 3)
{
printf("Au revoir!\n");
close(sockfd);
close(connAfd);
break;
}
}//fine del while
exit(0); //chiude i descrittori, tutte le risorse allocate, uccide il processo (incorporata la close())
}
/**
Client Admin
*/
#include <stdio.h>
#include <stdlib.h> //exit
#include <unistd.h> //read
#include <sys/types.h> //socket,connect
#include <sys/socket.h> //socketconnect
#include <arpa/inet.h> //struct sockaddr_in
typedef struct {
int id;
int disponibile; //0 libero 1 occupato
} Muletti;
int main(int argc,char *argv[])
{
int nread, nwrite;
int sockfd,i=0, sockMfd;
struct sockaddr_in servaddr;
struct sockaddr_in clientMuletaddr;
int conferma = 0;
int ordine;
//struct muletti
Muletti muletti[4];
muletti[4]={2,2,2,2};
// controllo sugli argomenti
if (argc != 2) {
fprintf(stderr,"usage: %s <IPaddress>\n",argv[0]);
exit (1);
}
printf("1\n");
/*
1 paramentro famiglia di protocolli di rete
2 paramentro canale di comunicazione tcp
3 parametro non analizzato perchè i primi due specificano il protocollo utilizzato
*/
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr,"socket error\n");
exit (1);
}
printf("2\n");
/*
Devo specificare i parametri della connessione
La struttura di base che vale per tutti i protocolli è sockaddr.
In particolare, noi usiamo sockaddr_in.
Primo paramentro: famiglia
Secondo: porta
Terzo: IP address che è un altra struttura (stringa di 32 bit)
*/
servaddr.sin_family = AF_INET;
printf("3\n");
/*
La porta su cui è in attesa il server.. htons è una funzione per la
conversione host to network in formato big endian per la rete
(s e l finale indicano short e long)
Fra gli indirizi internet utilizzabili nel campo "sin_addr" (definiti in "netinet/in.h")
ci sono "INADDR_ANY" (vengono accettati dati da qualunque parte vengano),
"INADDR_BROADCAST" (per mandare dati a tutti gli host),
"INADDR_LOOPBACK" (loopback sull'host locale).
*/
servaddr.sin_port = htons(35952);
printf("4\n");
/*
Indirizzo ip del server con cui devo andarmi a collegare.
*/
//Converte l'indirizzo espresso tramite una stringa nel valore numerico.
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0)
{
fprintf(stderr,"inet_pton error for %s\n", argv[1]);
exit (1);
}
printf("5\n");
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0)
{
fprintf(stderr,"connect error\n");
exit(1);
}
printf("Client admin invia richiesta per id muletto libero\n");
if(nwrite = write(sockfd,(void *) &muletti[i].id,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
if(nread = read(sockfd,(void *) &muletti[i].id,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
printf("Muletto disponibile ha id = %d\n",muletti[i].id);
if(muletti[i].id >= 4)
{
sleep(120);
}
/*CONNESSIONE MULETTO*/
printf("1\n");
/*
1 paramentro famiglia di protocolli di rete
2 paramentro canale di comunicazione tcp
3 parametro non analizzato perchè i primi due specificano il protocollo utilizzato
*/
if ((sockMfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr,"socket error\n");
exit (1);
}
printf("2\n");
/*
Devo specificare i parametri della connessione
La struttura di base che vale per tutti i protocolli è sockaddr.
In particolare, noi usiamo sockaddr_in.
Primo paramentro: famiglia
Secondo: porta
Terzo: IP address che è un altra struttura (stringa di 32 bit)
*/
clientMuletaddr.sin_family = AF_INET;
printf("3\n");
/*
La porta su cui è in attesa il server.. htons è una funzione per la
conversione host to network in formato big endian per la rete
(s e l finale indicano short e long)
Fra gli indirizi internet utilizzabili nel campo "sin_addr" (definiti in "netinet/in.h")
ci sono "INADDR_ANY" (vengono accettati dati da qualunque parte vengano),
"INADDR_BROADCAST" (per mandare dati a tutti gli host),
"INADDR_LOOPBACK" (loopback sull'host locale).
*/
clientMuletaddr.sin_port = htons(35953+muletti[i].id);
printf("4\n");
/*
Indirizzo ip del server con cui devo andarmi a collegare.
*/
//Converte l'indirizzo espresso tramite una stringa nel valore numerico.
if(inet_pton(AF_INET, argv[1], &clientMuletaddr.sin_addr) < 0)
{
fprintf(stderr,"inet_pton error for %s\n", argv[1]);
exit (1);
}
printf("5\n");
if (connect(sockMfd, (struct sockaddr *) &clientMuletaddr, sizeof(clientMuletaddr)) < 0)
{
fprintf(stderr,"connect error\n");
exit(1);
}
printf("OPERAZIONI POSSIBILI : \n1) Prelievo \n2) Deposito \n3) Disconnetti \n\n");
scanf("%d",&ordine);
if(nwrite = write(sockMfd,(void *) &ordine,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
printf("Client admin attende avvenuta operazione da parte del muletto..\n");
if(nread = read(sockMfd,(void *) &conferma,sizeof(int))<0)
{
perror("Read error\n");
exit(1);
}
printf("Client admin invia avvenuta operazione da parte del muletto\n");
conferma = 1;
printf("conferma = %d\n", conferma);
if(nwrite = write(sockfd,(void *) &conferma,sizeof(int))<0)
{
perror("Write error\n");
exit(1);
}
}
Grazie in anticipo per i consigli