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) |
libreria di comunicazione server client
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.
| #define MAXCONN 20 |
| #define MAXSLEEP 128 |
| serverChannel_t createServerChannel | ( | const char * | path | ) |
Crea un channel di ascolto AF_UNIX
| path | pathname del canale di ascolto da creare |
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
| s | il channel di ascolto da distruggere |
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
| s | channel di ascolto su cui si vuole ricevere la connessione |
legge un messaggio dal channel di trasmissione
| sc | channel di trasmissione | |
| msg | struttura che conterra' il messagio letto (deve essere allocata all'esterno della funzione, tranne il campo buffer) |
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 }
scrive un messaggio sul channel di trasmissione
| sc | channel di trasmissione | |
| msg | struttura che contiene il messaggio da scrivere |
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
| sc | il descrittore del channel da chiudere |
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
| path | nome del server socket |
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 }
1.6.3