Posto qui il codice:
Questa è la parte "interessante" del client
int connfd;
// faccio 10 tentativi aspettando 1 secondo
if ((connfd=openConnection(spath, 10, 1))<0) {
fprintf(stderr, "error trying to connect...\n");
free(ops);
return -1;
}
La funzione openConnection è questa
/**
* @function openConnection
* @brief Apre una connessione AF_UNIX verso il server membox.
*
* @param path Path del socket AF_UNIX
* @param ntimes numero massimo di tentativi di retry
* @param secs tempo di attesa tra due retry consecutive
*
* @return il descrittore associato alla connessione in caso di successo
* -1 in caso di errore
*/
int openConnection(char* path, unsigned int ntimes, unsigned int secs){
int retry; /* conta il numero di tentativi di connessione */
int socket_fd; /* fd della socket del client */
struct sockaddr_un socket_address; /* indirizzo socket */
/* controllo sui parametri ntimes e secs */
if( (ntimes > MAX_RETRIES) || (secs > 3) ){
fprintf(stderr, "Parametri non validi\n");
return -1;
}
/* Preparo il sockaddr */
strncpy(socket_address.sun_path, path, sizeof(socket_address));
socket_address.sun_family = AF_UNIX;
/* Creo la socket */
socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if(socket_fd < 0){
perror("Errore aprendo la socket");
return -1;
}
retry = 0;
while(retry<ntimes){
if( connect(socket_fd, (struct sockaddr *) &socket_address, UNIX_PATH_MAX) == 0 )
return socket_fd;
else
sleep(secs);
retry++;
}
perror("Impossibile aprire una connessione col server");
return -1;
}
Una volta stabilita la connessione, il client fa questo:
int r=0;
for(int i=0;i<k;++i) {
r = execute_op(connfd, &ops[i]);
if (r == 0) printf("Successo!\n\n\n---------------------------------------------------------------------\n\n");
else break; // non appena una operazione fallisce esco
static int execute_op(int connfd, operation_t *o) {
message_t msg;
setData(&msg, NULL, 0);
setHeader(&msg, op, &key);
if (op == PUT_OP || op == UPDATE_OP) {
char *buf = malloc(size);
if (buf == NULL) {
perror("malloc");
return -1;
}
init_data(&key, buf, size);
setData(&msg, buf, size);
}
printf("Il client ");
if (sendRequest(connfd, &msg) == -1 && (errno != EPIPE)) {
perror("request");
return -1;
}
}
dove la sendRequest è così definita
// ------- client side ------
/**
* @function sendRequest
* @brief Invia un messaggio di richiesta al server membox
*
* @param fd descrittore della connessione
* @param msg puntatore al messaggio da inviare
*
* @return 0 in caso di successo -1 in caso di errore
*/
int sendRequest(long fd, message_t *msg){
int hdr, body;
printf("sta inviando il messaggio: key=%lu, op=%d, len=%d\n", msg->hdr.key, msg->hdr.op, msg->data.len);
hdr = write(fd, (struct message_t *) msg, sizeof(message_t));
if( hdr < 0){
perror("Problema nella scrittura del messaggio");
return -1;
}
if(msg->data.buf!=NULL){
body = write(fd, msg->data.buf, msg->data.len);
if( body < 0){
perror("Problema nella scrittura dell'oggetto del messaggio");
return -1;
}
}
printf("Ho scritto %d byte di messaggio e %d byte di dati\n", hdr, body);
return 0;
}
Questa stessa funzione, la sendRequest, viene usata dal server che fa esattamente quello che ci si aspetta.