1
0
mirror of https://github.com/thearcanum/WIFSS synced 2025-07-22 16:00:36 +02:00

Initial commit

This commit is contained in:
TheArcanum
2015-05-01 22:17:29 +02:00
parent 0abca9fac7
commit 0a1ce901ee
5 changed files with 294 additions and 0 deletions

46
inc/server.h Normal file

@@ -0,0 +1,46 @@
#ifndef __SERVER__
#define __SERVER__
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netdb.h>
#include <pthread.h>
#include <str.h>
#define PORT 12444
#define BSIZE 512
#define MAX_CLIENTS 4
#define FREE 1
#define TAKEN 2
#define SID -1
#define RUNNING 1
#define STOPPING 2
struct client_t
{
struct sockaddr_in addr;
int sock;
unsigned int id;
int status;
};
struct client_t g_clients[MAX_CLIENTS];
unsigned int count;
pthread_t threads[MAX_CLIENTS];
pthread_t command_thread;
int isvalid(const char *);
void broadcast(int, const char *);
void close_all_connections();
int process_command(const char*, int);
void* command_handler(void* data);
void* on_connection(void *data);
int start_server(void);
#endif

12
inc/str.h Normal file

@@ -0,0 +1,12 @@
#ifndef __STR__
#define __STR__
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* Renvoie 1 si la chaine w commence par s */
int str_beginwith(const char *w,const char *s);
#endif

27
src/command.c Normal file

@@ -0,0 +1,27 @@
#include <server.h>
void* command_handler(void* data)
{
char buffer[BSIZE] = "";
int running = 1;
int i;
while(running)
{
scanf("%s", buffer);
if(str_beginwith(buffer, "STOP")) {
broadcast(SID, "[WIFSS] Le serveur va être arrêté.\n");
close_all_connections();
for(i=0;i<MAX_CLIENTS;i++)
pthread_cancel(threads[i]);
running = 0;
}
}
printf("[WIFSS] Serveur arrêté.\n");
exit(0);
return data;
}

196
src/server.c Normal file

@@ -0,0 +1,196 @@
#include <server.h>
int isvalid(const char *s)
{
// pour se déconnecter un client envoie une chaine commencant par "qxt"
if(str_beginwith(s, "quit"))
return 0;
return 1;
}
void broadcast(int sender, const char *msg)
{
int i;
for(i=0;i<MAX_CLIENTS;i++) {
if(i != sender) {
send(g_clients[i].sock, msg, BSIZE, 0);
}
}
}
void close_all_connections()
{
int i;
printf("[WIFSS] Fermeture de toutes les connections.... ");
for(i=0;i<MAX_CLIENTS;i++)
close(g_clients[i].sock);
printf("fait.\n");
}
int process_command(const char* command, int sender_id)
{
char cpy[BSIZE] = ""; // Pour copier le message
if(str_beginwith(command, "download")) {
int remote_id = -1;
char filename[BSIZE] = "";
printf("[Client %d] Demande de téléchargement !\n", sender_id);
sscanf(command, "download %s %d", filename, &remote_id);
printf("[Client %d] Fichier : \"%s\" de %d\n", sender_id, filename, remote_id);
if((remote_id > (MAX_CLIENTS - 1)) || (remote_id < 0)) {
send(g_clients[sender_id].sock, "Erreur : Le client demandé n'existe pas..\n",
52, 0);
return 0;
}
if(g_clients[remote_id].sock <= 0) {
send(g_clients[sender_id].sock, "Erreur : Le client demandé n'est pas connecté..\n",
52, 0);
return 0;
}
return 0;
}
if(str_beginwith(command, "quit")) {
close(g_clients[sender_id].sock);
return 1;
}
memset(cpy, 0, BSIZE);
sprintf(cpy, "[Client %d] : %s", sender_id, command);
broadcast(sender_id,cpy);
return 1;
}
void* on_connection(void *data)
{
char buffer[BSIZE] = "";
int res;
struct client_t client = *((struct client_t*)data);
printf("[WIFSS] Connexion reçue de %s\n", inet_ntoa(client.addr.sin_addr));
sprintf(buffer, "[Client %d] Se connecte.\n", client.id);
broadcast(client.id, buffer);
while(client.sock > 0)
{
memset(buffer, 0, BSIZE);
res = recv(client.sock, buffer, BSIZE, 0);
if(res <= 0) {
break; // Le client s'est déco
}
printf("[Client %d] Reçu : %s", client.id, buffer);
printf("[Client %d] Broadcast aux autres clients.\n", client.id);
process_command(buffer, client.id);
}
printf("[Client %d] Déconnexion..\n", client.id);
sprintf(buffer, "(Le client %d se déconnecte.)\n", client.id);
broadcast(client.id, buffer);;
close(client.sock);
g_clients[client.id].status = FREE;
return NULL;
}
int start_server(void)
{
int res = 0, i;
struct sockaddr_in client;
struct sockaddr_in server;
int listen_socket, sock;
unsigned int current_id = 0, asize;
server.sin_port = htons(PORT);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
res = bind(listen_socket, (struct sockaddr*)&server, sizeof(server));
if(res < 0) {
printf("Erreur bind (%d)\n", res);
return res;
}
listen(listen_socket, MAX_CLIENTS);
printf("[WIFSS] Initialisation de la liste des clients..\n");
for(i=0;i<MAX_CLIENTS;i++) {
g_clients[i].status = FREE;
}
asize = sizeof(struct sockaddr_in);
printf("[WIFSS] Serveur allumé, attente de client..\n");
pthread_create(&command_thread, NULL, &command_handler, NULL);
while((sock = accept(listen_socket, (struct sockaddr*)&client, &asize)) && (count < MAX_CLIENTS) ) {
struct client_t new_client;
for(i=0;i<MAX_CLIENTS;i++) {
if(g_clients[i].status == FREE) {// Emplacement libre
current_id = i;
g_clients[i].status = TAKEN;
break;
}
}
printf("[WIFSS] Connexion reçue %s:%d -> numéro attribué %d \n", inet_ntoa(client.sin_addr), ntohs(client.sin_port),
current_id);
new_client.id = current_id;
new_client.addr = client;
new_client.sock = sock;
new_client.status = TAKEN;
g_clients[current_id] = new_client; // On le copie dans la structure globale
res = pthread_create(&threads[current_id], NULL, &on_connection, (void*)&new_client);
if(res != 0) {
printf("Erreur lors de la création du thread %d : Erreur %d \n", current_id, res);
broadcast(SID, "Erreur critique du serveur, arrêt.\n");
close_all_connections();
return res;
}
/* Calcule le nombre de clients connectés */
count = 0;
for(i=0;i<MAX_CLIENTS;i++) {
if(g_clients[i].status == TAKEN) {
count++;
}
}
printf("[WIFSS] Il y a %d client(s) connecté(s).\n", count);
}
if(count >= MAX_CLIENTS)
broadcast(SID, "Capacitié dépassée, arrêt du serveur.\n");
close_all_connections();
close(sock);
close(listen_socket);
return 0;
}
int main()
{
start_server();
return 0;
}

13
src/str.c Normal file

@@ -0,0 +1,13 @@
#include <str.h>
int str_beginwith(const char *w,const char *s)
{
while(*s) {
if(*s != *w) {
return 0;
}
w++;
s++;
}
return 1;
}