This repository was archived by the owner on Nov 4, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
chat : server : server.c\.h
sᴀʟᴠᴀᴛᴏʀᴇ ʙ edited this page Jul 23, 2017
·
1 revision
// file descriptor del server
extern int server_pipe;
extern char* server_pipe_path;
void start();
void stop();
void getClientPipePath(pid_t pid, char* bufferPath);
int readCommand(char **str);
void getFirstField(char keyword[20], char* cmd);
void getPidFromCmd(char* cmd, pid_t* pid);
int getPipeByPid(pid_t pid, Client* head);
Client* getLastClient(Client *head);void start() {
createPipe(server_pipe_path);
openServerPipe();
// l'apertura non deve essere bloccante, ma le successive read sì, perciò modifico i flag
int saved_flags = fcntl(server_pipe, F_GETFL);
// maschero O_NONBLOCK
fcntl(server_pipe, F_SETFL, saved_flags & (~O_NONBLOCK));
}La funzione start() richiama la creazione ed apertura della server_pipe, infine modifica i flag del descrittore del file in modo che le successive read siano bloccanti.
void openServerPipe() {
/* apertura della server_pipe in lettura e ovviamente
* non bloccante, dato che non è necessario che esistano client gia' in attesa*/
server_pipe = open(server_pipe_path, O_RDONLY | O_NONBLOCK);
if (server_pipe == -1) {
printf("\n[ERROR] (%s) Pipe creata ma inutilizzabile",
server_pipe_path);
} else if (verboseMode == 1) {
printf("\n[LOG] %s: pipe pronta all'utilizzo", server_pipe_path);
fflush(stdout);
}
} void stop() {
closeConnection(server_pipe, server_pipe_path);
}/* Ritorna il nome completo della pipe di un client
* pid + "_client_pipe" */
void getClientPipePath(pid_t pid, char* bufferPath) {
sprintf(bufferPath, "./%d%s", pid, "_client_pipe");
}/* Ritorna un puntatore all'ultimo client della lista */
Client* getLastClient(Client *head) {
if (head == NULL) {
return NULL;
}
Client *last = head;
while (last->next != NULL) {
last = last->next;
}
return last;
}/*
* Legge il comando ricevuto in server_pipe, inserendolo in "str"
* Restituisce 1 se è presente un comando nella stringa, altrimenti 0
*/
int readCommand(char **str) {
int dim = 512;
/* non essendo possibile prevedere la lunghezza massima del messaggio ricevuto
* si alloca dinamicamente lo spazio del buffer
*/
*str = realloc(*str, sizeof(char) * dim);
char* temp = *str;
int n, count = 0;
do { // Legge fino a '\0' o EOF
/*
* Nota: la read è bloccante fino a che c'è almeno un client connesso,
* altrimenti legge EOF ed esce, rientrando ed uscendo all'infinito.
*/
n = read(server_pipe, temp, 1);
if (n != 0) {
count++;
if (count == dim) {
//rialloco il doppio della dimensione precedente
temp = realloc(temp, sizeof(char) * (dim * 2));
dim *= 2;
temp += (count - 1); //riposiziono il puntatore
}
} else {
**str = '\0';
}
} while (n > 0 && *temp++ != '\0');
return n;
}La funzione readCommand() salva in un buffer temporaneo ogni singolo carattere letto dalla server_pipe, non essendo nota la dimensione si allocano inizialmente 512 byte, che vengono raddoppiati se il messaggio risulta più lungo (che sarà comunque minore o uguale a 4096 byte)
/*
* Acquisisce il primo campo della stringa ricevuta,
* ovvero la keyword che identifica il tipo di comando e
* la inserisce nella variabile keyword
*/
void getFirstField(char keyword[20], char* cmd) {
int i = 0;
while (*cmd != ' ' && *cmd != '\0') {
keyword[i] = *cmd;
cmd++;
i++;
}
keyword[i] = '\0';
}/*
* Ottiene il pid dai comandi con la seguente sintassi
* "<COMMAND> <pid>"
*/
void getPidFromCmd(char* cmd, pid_t* pid) {
int i = 0;
char temp[20];
// raggiungo il primo spazio
while (*cmd != ' ') {
cmd++;
}
cmd++;
// copio il pid
while (*cmd != '\0') {
temp[i] = *cmd;
cmd++;
i++;
}
temp[i] = '\0';
*pid = strtol(temp, NULL, 10);
}La funzione getPidFromCmd è utilizzabile per i comandi come LIST, CONNECT e DISCONNECT, i quali sono seguiti dal pid del client interessato.
/* Ottiene il file descriptor della pipe del client individuato da pid.
* Restituisce 0 se il client non esiste, altrimenti restituisce il fd.*/
int getPipeByPid(pid_t pid, Client* head) {
if (head == NULL) {
return 0;
} else {
int found = 0;
do {
if (head->pid == pid)
// il valore della pipe sarà sicuramente diverso da 0
found = head->pipe;
head = head->next;
} while (found == 0 && head != NULL);
return found;
}
}Made with ❤️ by Owanesh and MatteoMauro | MIT ©