Riferimenti per il file lcscom.h

libreria di comunicazione server client Continua...

#include "com_defs.h"

Vai al codice sorgente di questo file.

Definizioni

#define MAXCONN   20
#define MAXSLEEP   128

Funzioni

serverChannel_t createServerChannel (const char *path)
int closeSocket (serverChannel_t s)
channel_t acceptConnection (serverChannel_t s)
int receiveMessage (channel_t sc, message_t *msg)
int sendMessage (channel_t sc, message_t *msg)
int closeConnection (channel_t sc)
channel_t openConnection (const char *path)

Descrizione dettagliata

libreria di comunicazione server client

Autore:
lcs07 Libreria che definisce l'interfaccia di comunicazione fra client e server (canali di comunicazione realizzati con socket AF_UNIX)

This program is free software; you can redistribuite it and/or modify it under the terms of the GNU/General Pubblic License as published the Free software Foundation; either version 2 of the License, or (at your opinion) any later version.

Definizione nel file lcscom.h.


Documentazione delle definizioni

#define MAXCONN   20

Numero di connessioni massime accettate

Definizione alla linea 22 del file lcscom.h.

#define MAXSLEEP   128

Tempo di ritardo sulla connessione sul socket, 128-> 2 minuti. Si prega, calorosamente, di non toccare questo valore. (^_^)

Definizione alla linea 27 del file lcscom.h.


Documentazione delle funzioni

serverChannel_t createServerChannel ( const char *  path  ) 

Crea un channel di ascolto AF_UNIX

Parametri:
path pathname del canale di ascolto da creare
Restituisce:
  • s il descrittore del channel di ascolto (s>0)
  • -1 in casi di errore (sets errno)
  • SFATENAMETOOLONG se il nome del socket eccede UNIX_PATH_MAX

Definizione alla linea 21 del file lcscom.c.

00021                                                      {
00022         serverChannel_t server_sk;
00023         struct sockaddr_un servaddr;     /* address of server */
00024     
00025         /* Creo il socket */
00026         if ((server_sk = socket(AF_UNIX,SOCK_STREAM,0)) < 0){
00027                 errore(__FILE__,__LINE__,"Server: socket create",errno);
00028                 return -1;
00029         }
00030         if (strlen(path) > UNIX_PATH_MAX){
00031                 errore(__FILE__,__LINE__,"Server: socket path too long (exceeding UNIX_PATH_MAX)",errno);    
00032                 return SFATENAMETOOLONG;
00033         }    
00034         memset(&servaddr, 0, sizeof(struct sockaddr_un));       /* Puliamo la struttura */  
00035         servaddr.sun_family = AF_UNIX;
00036         strncpy(servaddr.sun_path, path, UNIX_PATH_MAX);
00037     
00038         /* Rendiamo il socket visibile nel dominio */
00039         if (bind(server_sk, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_un)) < 0){
00040                 close(server_sk);
00041                 errore(__FILE__,__LINE__,"Server: socket bind",errno);
00042                 return -1;     
00043         }
00044 
00045         /* Mettiamo il socket in attesa di connessioni */
00046         if (listen(server_sk,MAXCONN) < 0){
00047                 close(server_sk);
00048                 errore(__FILE__,__LINE__,"Server: socket listen",errno);                
00049                 return -1;
00050         }
00051         return server_sk;
00052 }

int closeSocket ( serverChannel_t  s  ) 

Distrugge un channel di ascolto

Parametri:
s il channel di ascolto da distruggere
Restituisce:
  • 0 se tutto ok,
  • -1 se errore (sets errno)

Definizione alla linea 55 del file lcscom.c.

00055                                   {
00056         /* Chiudo la socket in lettura e scrittura (invio SEOF al client) */
00057         if (shutdown(s, SHUT_RDWR) == -1){
00058                 errore(__FILE__,__LINE__,"client: socket shutdown",errno);              
00059                 return -1;      
00060         }       
00061         if (close(s)){
00062                 errore(__FILE__,__LINE__,"Server: socket close",errno);         
00063                 return -1;      
00064         }
00065         return 0;
00066 }

channel_t acceptConnection ( serverChannel_t  s  ) 

accetta una connessione da parte di un client

Parametri:
s channel di ascolto su cui si vuole ricevere la connessione
Restituisce:
  • c il descrittore del channel di trasmissione con il client
  • -1 in casi di errore (sets errno)

Definizione alla linea 70 del file lcscom.c.

00070                                              {
00071         channel_t  sk_comunication;
00072         
00073         /* In caso di errore la funzione accept ritorna -1 */
00074         if ((sk_comunication = accept(s, NULL, 0)) == -1)
00075                 errore(__FILE__,__LINE__,"Server: socket accept",errno);
00076         return sk_comunication;
00077 }

int receiveMessage ( channel_t  sc,
message_t msg 
)

legge un messaggio dal channel di trasmissione

Parametri:
sc channel di trasmissione
msg struttura che conterra' il messagio letto (deve essere allocata all'esterno della funzione, tranne il campo buffer)
Restituisce:
  • -1 se errore (errno settato),
  • SEOF se EOF sul socket
  • lung lunghezza del buffer letto, se OK

Definizione alla linea 115 del file lcscom.c.

00115                                                 {
00116         int letti, read_cnt;
00117         if ((letti = read(sc, &(msg->type), sizeof(char))) < 0 ){
00118                 errore(__FILE__,__LINE__,"Error read message 'type'",errno);
00119                 return -1;              
00120         }else if (letti==0) return SEOF; /* EOF sul socket */
00121         read_cnt = letti;
00122         if ((letti = read(sc, &(msg->length), sizeof(unsigned int))) < 0){
00123                 errore(__FILE__,__LINE__,"Error read message 'length'",errno);
00124                 return -1;              
00125         }else if (letti==0) return SEOF; /* EOF sul socket */
00126         read_cnt += letti;
00127         
00128         if (msg->length!=0){
00129                 /* alloco il buffer di di lenght + 1 al fine di terminare la stringa */
00130                 if (!(msg->buffer = calloc(msg->length +1, sizeof(char)))){
00131                         errore(__FILE__,__LINE__,"Error calloc 'buffer'",errno);
00132                         return -1;                      
00133                 }
00134                 if ((letti = read(sc, msg->buffer, msg->length)) <= 0){
00135                         errore(__FILE__,__LINE__,"Error read message 'buffer'",errno);
00136                         free(msg->buffer);
00137                         msg->buffer = NULL;
00138                         if (letti==0) return SEOF; /* EOF sul socket */
00139                         return -1;
00140                 }
00141                 read_cnt += letti;
00142         }else
00143                 msg->buffer = NULL;
00144 
00145         return read_cnt;
00146 }

int sendMessage ( channel_t  sc,
message_t msg 
)

scrive un messaggio sul channel di trasmissione

Parametri:
sc channel di trasmissione
msg struttura che contiene il messaggio da scrivere
Restituisce:
  • -1 se errore (sets errno)
  • n il numero di caratteri inviati (se OK)

Definizione alla linea 81 del file lcscom.c.

00081                                              {
00082         int char_sent, sent;
00083         int nsec;
00084         
00085         /* write ritorna -1 in caso di errore, altrimenti il numero di caratteri scritti */
00086         /* Temporizzazione in caso di errore. (^l^) */
00087         for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){
00088                 if ((sent = write(sc, &(msg->type), sizeof(char))) != -1) break;
00089                 if (nsec<=MAXSLEEP/2) sleep(nsec);
00090         }
00091         if (sent==-1){ errore(__FILE__,__LINE__,"Error send message 'type'",errno); return -1; }
00092         char_sent = sent;
00093         
00094         for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){
00095                 if ((sent = write(sc, &(msg->length), sizeof(unsigned int))) != -1) break;
00096                 if (nsec<=MAXSLEEP/2) sleep(nsec);
00097         }
00098         if (sent==-1){ errore(__FILE__,__LINE__,"Error send message 'length'",errno); return -1; }
00099         char_sent += sent;
00100 
00101         if (msg->length!=0){
00102                 for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){
00103                         if ((sent = write(sc, msg->buffer, msg->length)) != -1) break;
00104                         if (nsec<=MAXSLEEP/2) sleep(nsec);
00105                 }
00106                 if (sent==-1){ errore(__FILE__,__LINE__,"Error send message 'buffer'",errno); return -1; }              
00107                 char_sent += sent;
00108         }
00109         if (msg->buffer) free(msg->buffer);
00110         msg->buffer = NULL;
00111         return char_sent;
00112 }

int closeConnection ( channel_t  sc  ) 

Chiude un socket

Parametri:
sc il descrittore del channel da chiudere
Restituisce:
  • 0 se tutto ok
  • -1 se errore (sets errno)

Definizione alla linea 149 del file lcscom.c.

00149                                  {
00150         /* Chiudo la socket lato client (invio SEOF al server) */
00151         if (shutdown(sc, SHUT_WR) == -1){
00152                 errore(__FILE__,__LINE__,"client: socket shutdown",errno);              
00153                 return -1;      
00154         }
00155         if (close(sc)){
00156                 errore(__FILE__,__LINE__,"client: socket close",errno);         
00157                 return -1;      
00158         }
00159         return 0;
00160 }

channel_t openConnection ( const char *  path  ) 

crea un channel di trasmissione verso il server

Parametri:
path nome del server socket
Restituisce:
  • c (c>0) il channel di trasmissione
  • -1 in casi di errore (sets errno)
  • SFATENAMETOOLONG se il nome del socket eccede UNIX_PATH_MAX

Definizione alla linea 163 del file lcscom.c.

00163                                           {
00164         channel_t client_sk;
00165         struct sockaddr_un clientaddr;     /* address of server */
00166     int nsec;
00167     
00168         /* Creo il socket */
00169         if ((client_sk = socket(AF_UNIX,SOCK_STREAM,0)) < 0){
00170                 errore(__FILE__,__LINE__,"Client: socket create",errno);
00171                 return -1;
00172         }
00173         if (strlen(path) > UNIX_PATH_MAX ){
00174                 errore(__FILE__,__LINE__,"Client: socket path too long (exceeding UNIX_PATH_MAX)",errno);    
00175                 return SFATENAMETOOLONG;
00176         }
00177         memset(&clientaddr, 0, sizeof(struct sockaddr_un));     /* Puliamo la struttura */  
00178         clientaddr.sun_family = AF_UNIX;
00179         strncpy(clientaddr.sun_path, path, UNIX_PATH_MAX);
00180     
00181         /* Connessione con riprova */
00182         for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){
00183                 /* Richiedo la connessione alla socket del server */
00184                 if (connect(client_sk, (struct sockaddr *)&clientaddr, sizeof(struct sockaddr_un)) == 0)
00185                         return client_sk;
00186                 if (nsec<=MAXSLEEP/2) sleep(nsec);
00187         }
00188         errore(__FILE__,__LINE__-3,"Client: socket connect",errno);
00189         return -1;
00190 }

Generato il Sat Jan 29 15:05:41 2011 per SFAT: Simplified File Allocation Table Project da  doxygen 1.6.3