#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "Include/common.h"
#include "Include/lcscom.h"
Vai al codice sorgente di questo file.
Funzioni | |
serverChannel_t | createServerChannel (const char *path) |
int | closeSocket (serverChannel_t s) |
channel_t | acceptConnection (serverChannel_t s) |
int | sendMessage (channel_t sc, message_t *msg) |
int | receiveMessage (channel_t sc, message_t *msg) |
int | closeConnection (channel_t sc) |
channel_t | openConnection (const char *path) |
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.c.
serverChannel_t createServerChannel | ( | const char * | path | ) |
Crea un channel di ascolto AF_UNIX
path | pathname del canale di ascolto da creare |
Definizione alla linea 20 del file lcscom.c.
00020 { 00021 serverChannel_t server_sk; 00022 struct sockaddr_un servaddr; /* address of server */ 00023 00024 /* Creo il socket */ 00025 if ((server_sk = socket(AF_UNIX,SOCK_STREAM,0)) < 0){ 00026 errore(__FILE__,__LINE__,"Server: socket create",errno); 00027 return -1; 00028 } 00029 if (strlen(path) > UNIX_PATH_MAX){ 00030 errore(__FILE__,__LINE__,"Server: socket path too long (exceeding UNIX_PATH_MAX)",errno); 00031 return SFATENAMETOOLONG; 00032 } 00033 memset(&servaddr, 0, sizeof(struct sockaddr_un)); /* Puliamo la struttura */ 00034 servaddr.sun_family = AF_UNIX; 00035 strncpy(servaddr.sun_path, path, UNIX_PATH_MAX); 00036 00037 /* Rendiamo il socket visibile nel dominio */ 00038 if (bind(server_sk, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_un)) < 0){ 00039 close(server_sk); 00040 errore(__FILE__,__LINE__,"Server: socket bind",errno); 00041 return -1; 00042 } 00043 00044 /* Mettiamo il socket in attesa di connessioni */ 00045 if (listen(server_sk,MAXCONN) < 0){ 00046 close(server_sk); 00047 errore(__FILE__,__LINE__,"Server: socket listen",errno); 00048 return -1; 00049 } 00050 return server_sk; 00051 }
int closeSocket | ( | serverChannel_t | s | ) |
Distrugge un channel di ascolto
s | il channel di ascolto da distruggere |
Definizione alla linea 54 del file lcscom.c.
00054 { 00055 /* Chiudo la socket in lettura e scrittura (invio SEOF al client) */ 00056 if (shutdown(s, SHUT_RDWR) == -1){ 00057 errore(__FILE__,__LINE__,"client: socket shutdown",errno); 00058 return -1; 00059 } 00060 if (close(s)){ 00061 errore(__FILE__,__LINE__,"Server: socket close",errno); 00062 return -1; 00063 } 00064 return 0; 00065 }
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 |
scrive un messaggio sul channel di trasmissione
sc | channel di trasmissione | |
msg | struttura che contiene il messaggio da scrivere |
Definizione alla linea 80 del file lcscom.c.
00080 { 00081 int char_sent, sent; 00082 int nsec; 00083 00084 /* write ritorna -1 in caso di errore, altrimenti il numero di caratteri scritti */ 00085 /* Temporizzazione in caso di errore. (^l^) */ 00086 for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){ 00087 if ((sent = write(sc, &(msg->type), sizeof(char))) != -1) break; 00088 if (nsec<=MAXSLEEP/2) sleep(nsec); 00089 } 00090 if (sent==-1){ errore(__FILE__,__LINE__,"Error send message 'type'",errno); return -1; } 00091 char_sent = sent; 00092 00093 for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){ 00094 if ((sent = write(sc, &(msg->length), sizeof(unsigned int))) != -1) break; 00095 if (nsec<=MAXSLEEP/2) sleep(nsec); 00096 } 00097 if (sent==-1){ errore(__FILE__,__LINE__,"Error send message 'length'",errno); return -1; } 00098 char_sent += sent; 00099 00100 if (msg->length!=0){ 00101 for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){ 00102 if ((sent = write(sc, msg->buffer, msg->length)) != -1) break; 00103 if (nsec<=MAXSLEEP/2) sleep(nsec); 00104 } 00105 if (sent==-1){ errore(__FILE__,__LINE__,"Error send message 'buffer'",errno); return -1; } 00106 char_sent += sent; 00107 } 00108 if (msg->buffer) free(msg->buffer); 00109 msg->buffer = NULL; 00110 return char_sent; 00111 }
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 114 del file lcscom.c.
00114 { 00115 int letti, read_cnt; 00116 if ((letti = read(sc, &(msg->type), sizeof(char))) < 0 ){ 00117 errore(__FILE__,__LINE__,"Error read message 'type'",errno); 00118 return -1; 00119 }else if (letti==0) return SEOF; /* EOF sul socket */ 00120 read_cnt = letti; 00121 if ((letti = read(sc, &(msg->length), sizeof(unsigned int))) < 0){ 00122 errore(__FILE__,__LINE__,"Error read message 'length'",errno); 00123 return -1; 00124 }else if (letti==0) return SEOF; /* EOF sul socket */ 00125 read_cnt += letti; 00126 00127 if (msg->length!=0){ 00128 /* alloco il buffer di di lenght + 1 al fine di terminare la stringa */ 00129 if (!(msg->buffer = calloc(msg->length +1, sizeof(char)))){ 00130 errore(__FILE__,__LINE__,"Error calloc 'buffer'",errno); 00131 return -1; 00132 } 00133 if ((letti = read(sc, msg->buffer, msg->length)) <= 0){ 00134 errore(__FILE__,__LINE__,"Error read message 'buffer'",errno); 00135 free(msg->buffer); 00136 msg->buffer = NULL; 00137 if (letti==0) return SEOF; /* EOF sul socket */ 00138 return -1; 00139 } 00140 read_cnt += letti; 00141 }else 00142 msg->buffer = NULL; 00143 00144 return read_cnt; 00145 }
int closeConnection | ( | channel_t | sc | ) |
Chiude un socket
sc | il descrittore del channel da chiudere |
Definizione alla linea 148 del file lcscom.c.
00148 { 00149 /* Chiudo la socket lato client (invio SEOF al server) */ 00150 if (shutdown(sc, SHUT_WR) == -1){ 00151 errore(__FILE__,__LINE__,"client: socket shutdown",errno); 00152 return -1; 00153 } 00154 if (close(sc)){ 00155 errore(__FILE__,__LINE__,"client: socket close",errno); 00156 return -1; 00157 } 00158 return 0; 00159 }
channel_t openConnection | ( | const char * | path | ) |
crea un channel di trasmissione verso il server
path | nome del server socket |
Definizione alla linea 162 del file lcscom.c.
00162 { 00163 channel_t client_sk; 00164 struct sockaddr_un clientaddr; /* address of server */ 00165 int nsec; 00166 00167 /* Creo il socket */ 00168 if ((client_sk = socket(AF_UNIX,SOCK_STREAM,0)) < 0){ 00169 errore(__FILE__,__LINE__,"Client: socket create",errno); 00170 return -1; 00171 } 00172 if (strlen(path) > UNIX_PATH_MAX ){ 00173 errore(__FILE__,__LINE__,"Client: socket path too long (exceeding UNIX_PATH_MAX)",errno); 00174 return SFATENAMETOOLONG; 00175 } 00176 memset(&clientaddr, 0, sizeof(struct sockaddr_un)); /* Puliamo la struttura */ 00177 clientaddr.sun_family = AF_UNIX; 00178 strncpy(clientaddr.sun_path, path, UNIX_PATH_MAX); 00179 00180 /* Connessione con riprova */ 00181 for (nsec = 1; nsec<=MAXSLEEP; nsec<<=1){ 00182 /* Richiedo la connessione alla socket del server */ 00183 if (connect(client_sk, (struct sockaddr *)&clientaddr, sizeof(struct sockaddr_un)) == 0) 00184 return client_sk; 00185 if (nsec<=MAXSLEEP/2) sleep(nsec); 00186 } 00187 errore(__FILE__,__LINE__-3,"Client: socket connect",errno); 00188 return -1; 00189 }