Prenons l'exemple d'un nombre max de 5. Si un 6ième client ce connecte, il doit être mis en attente. Donc il faut qu'un thread le capte, mais attende d'avoir le feu vert de la semaphore n'est ce pas ??!Théoriquement, oui.
Je pense qu'il faudrait que je sinde la partie écoute de connexions client, avec celle du traitement des requêtes des clients. Et ainsi pouvoir appliquer mon sémaphore qu'au traitement et laisser libre le nombre de connexions clients. Il seront juste mis en attente par la semaphore qui devrait réguler le nombre de traitement simultannées...Il faut surtout que tu évites de trop te prendre la tête. Généralement, on évite de recoder la roue. Je te conseille fortement l'utilisation de boost::asio (en plus y a des tutos), qui te simplifieront la vie.
Améliorez votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature
Améliorez votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionAméliorez votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature
//----------------------------------------------------------------------------------
// Phase de connexion
//----------------------------------------------------------------------------------
//attente de connexions client
printf("\tServeur en attente d'une connexion ...\n\n");
if(listen(sock, 2) != 0)
perror(">> Erreur de la fonction Listen");
else
{
while(1)
{
//Acceptation de la connexion
int sock_com = accept(sock, (struct sockaddr *) 0, (int *) 0);
if(sock_com == -1)
perror(">> Erreur de la fct Accept");
else
{
printf("\t...CONNEXION ETABLIE...\n\n");
//création d'un fils pour effectuer le traitement de chaque connexions
int pidFils;
pidFils = fork();
if(pidFils < 0) // (pid < 0) => Erreur
perror("Erreur de création du fils pour la géstion de la connexion");
else if(pidFils == 0)// (pid == 0) => Fils
{
//fils
gestionConnexionClientTCP(sock_com);
exit(0);
}
}
}
}
//----------------------------------------------------------------------------------
// Phase de connexion
//----------------------------------------------------------------------------------
//attente de connexions client
printf("\tServeur en attente d'une connexion ...\n\n");
if(listen(sock, 2) != 0)
perror(">> Erreur de la fonction Listen");
else
{
while(1)
{
//Acceptation de la connexion
int sock_com = accept(sock, (struct sockaddr *) 0, (int *) 0);
if(sock_com == -1)
perror(">> Erreur de la fct Accept");
else
{
printf("\t...CONNEXION ETABLIE...\n\n");
//CREATION d'un thread fils pour effectuer le traitement de chaque connexions ?????????
pthread_t thread_gestionCo;
if(pthread_create(&thread_gestionCo, NULL, thread_GestionConnexionClientTCP, (void*) sock_com) != 0)//si la création a foiré : renvoi != 0
printf("ERREUR de creation du thread\n");
}
}
}
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #define MAXRCVLEN 500 #define PORTNUM 2343 int main(int argc, char *argv[]) { char buffer[MAXRCVLEN + 1]; /* +1 so we can add null terminator */ int len, mysocket; struct sockaddr_in dest; mysocket = socket(AF_INET, SOCK_STREAM, 0); memset(&dest, 0, sizeof(dest)); /* zero the struct */ dest.sin_family = AF_INET; dest.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* set destination IP number - localhost, 127.0.0.1*/ dest.sin_port = htons(atoi(argv[1])); /* set destination port number */ if (connect(mysocket, (struct sockaddr *)&dest, sizeof (struct sockaddr))) { perror("connect error!"); exit(1); } send(mysocket, "Coucou c'est moi le client", strlen("Coucou c'est moi le client"), 0); len = recv(mysocket, buffer, MAXRCVLEN, 0); if (len > 0) { /* We have to null terminate the received data ourselves */ buffer[len] = '\0'; printf("Received %s (%d bytes).\n", buffer, len); } else { if (len < 0) perror("recv"); else printf("Server closed connection\n"); } close(mysocket); return EXIT_SUCCESS; }
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/epoll.h> #include <netdb.h> #include <fcntl.h> #include <errno.h> #define MAXEVENTS 64 /* Assume that tab finish by 0 */ static int is_in_tab(int val, int* tab) { while (tab && *tab) { if (*tab == val) return 1; ++tab; } return 0; } static int create_and_bind(char* port) { struct addrinfo hints; struct addrinfo* result; struct addrinfo* rp; int s; int sfd; memset(&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ hints.ai_flags = AI_PASSIVE; /* All interfaces */ if ((s = getaddrinfo(NULL, port, &hints, &result)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); return -1; } for (rp = result; rp != NULL; rp = rp->ai_next) { if ((sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1) continue; if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) break; close(sfd); } if (rp == NULL) { fprintf(stderr, "Could not bind\n"); return -1; } freeaddrinfo(result); return sfd; } static int make_socket_non_blocking(int sfd) { int flags; flags = fcntl(sfd, F_GETFL, 0); if (flags == -1) { perror("fcntl"); return -1; } flags |= O_NONBLOCK; if (fcntl(sfd, F_SETFL, flags) == -1) { perror("fcntl"); return -1; } return 0; } void add_socket_to_epoll(int sfd, int efd) { struct epoll_event event; if (make_socket_non_blocking(sfd) == -1) abort(); event.data.fd = sfd; event.events = EPOLLIN | EPOLLET; if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event) == -1) { perror("epoll_ctl"); abort(); } } int declare_socket(char* port, int efd) { int sfd; if (((sfd = create_and_bind(port)) == -1)) abort(); add_socket_to_epoll(sfd, efd); if (listen(sfd, SOMAXCONN) == -1) { perror("listen"); abort(); } return sfd; } /* We have a notification on the listening socket, which means one or more incoming connections. */ static void handle_incoming_connection(int sfd, int efd) { while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof (in_addr); infd = accept(sfd, &in_addr, &in_len); if (infd == -1) { /* We have processed all incoming connections. */ if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) perror("accept"); return; } if (getnameinfo(&in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV) == 0) { printf("Accepted connection on descriptor %d " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ add_socket_to_epoll(infd, efd); } } static char* handle_command(const char* cmd) { // Ici gérer l'ajout d'un thread printf("Cmd du client: %s\n", cmd); // Mettre le retour du serveur ou NULL si pas de retour. char* res = calloc(256, sizeof (char)); strncpy(res, "Bonjour du serveur", 256); return res; } /* We have data on the fd waiting to be read. Read and display it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ static int handle_session_socket_read(int fd) { unsigned int size = 0; unsigned int limit = 512; char* cmd = calloc(limit, sizeof (char)); char* res = NULL; int stop = 0; while (!stop) { ssize_t count; char buf[512]; count = read(fd, buf, sizeof (buf)); switch (count) { case -1: { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { perror("read"); return 1; } stop = 1; break; } case 0: /* End of file. The remote has closed the connection. */ return 1; default: size += count; if (size > limit) { limit *= 2; cmd = realloc(cmd, limit * sizeof (char)); } strncat(cmd, buf, count); } } res = handle_command(cmd); if (res) { write(fd, res, strlen(res)); free(res); } free(cmd); return 0; } static void event_loop(struct epoll_event* events, int* sfds, int efd) { while (1) { int i = 0; int n = epoll_wait(efd, events, MAXEVENTS, -1); for (i = 0; i < n; ++i) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf(stderr, "epoll error\n"); close(events[i].data.fd); } else if (is_in_tab(events[i].data.fd, sfds)) handle_incoming_connection(events[i].data.fd, efd); else if (handle_session_socket_read(events[i].data.fd)) { printf("Closed connection on descriptor %d\n", events[i].data.fd); /* Closing the descriptor will make epoll remove it from the set of descriptors which are monitored. */ close(events[i].data.fd); // /!\ Si utiilisation de thread, à déplacer ailleurs ! /!\ } } } } int main(int argc, char* argv[]) { int sfd[65535] = {0}; int efd; int i = 0; struct epoll_event* events; if (argc < 2) { fprintf(stderr, "Usage: %s port1 port2 etc...\n", argv[0]); exit(0); } if ((efd = epoll_create1(0)) == -1) { perror("epoll_create"); abort(); } for (i = 1; i < argc && i < 65535; ++i) sfd[i - 1] = declare_socket(argv[i], efd); events = calloc(MAXEVENTS, sizeof (struct epoll_event)); event_loop(events, sfd, efd); free(events); for (i = 1; i < argc && i < 65535; ++i) close(sfd[i - 1]); return 0; }
Améliorez votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #define MAXRCVLEN 500 #define PORTNUM 2343 int send_cmd(int mysocket, const char* cmd) { char buffer[MAXRCVLEN + 1]; /* +1 so we can add null terminator */ int len; send(mysocket, cmd, strlen(cmd), 0); len = recv(mysocket, buffer, MAXRCVLEN, 0); if (len > 0) { /* We have to null terminate the received data ourselves */ buffer[len] = '\0'; printf("Received %s (%d bytes).\n", buffer, len); return 1; } if (len < 0) perror("recv"); else printf("Server closed connection\n"); return 0; } int main(int argc, char* argv[]) { int mysocket; int stop = 0; struct sockaddr_in dest; if (argc < 2) { printf("Usage: %s [port]\n", argv[0]); return 1; } mysocket = socket(AF_INET, SOCK_STREAM, 0); memset(&dest, 0, sizeof(dest)); /* zero the struct */ dest.sin_family = AF_INET; dest.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* set destination IP number - localhost, 127.0.0.1*/ dest.sin_port = htons(atoi(argv[1])); /* set destination port number */ if (connect(mysocket, (struct sockaddr *)&dest, sizeof (struct sockaddr))) { perror("connect error!"); exit(1); } send_cmd(mysocket, "Coucou c'est moi le client"); while (!stop) { char buff[128] = {0}; printf("$ "); scanf("%s", buff); if (strcmp(buff, "quit") == 0) stop = 1; else send_cmd(mysocket, buff); } close(mysocket); return 0; }
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/epoll.h> #include <netdb.h> #include <fcntl.h> #include <errno.h> #include <pthread.h> #include <assert.h> typedef void (*process_func)(void* arg); typedef struct worker { process_func process; void* arg; struct worker* next; } thread_worker; typedef struct param { int* epoll_fd; int* accept_fd; int* maxfd; struct epoll_event* ev; } thread_param; typedef struct { pthread_mutex_t mutex; pthread_cond_t ready; pthread_t* thread; thread_worker* queue; int shutdown; int max_thread; int queue_size; } thread_pool; /* Assume that tab finish by 0 */ static int is_in_tab(int val, int* tab) { while (tab && *tab) { if (*tab == val) return 1; ++tab; } return 0; } static void* pool_thread_worker(void* arg) { thread_pool* pool = arg; printf("[Debug] Starting thread 0x%x\n", (unsigned int) pthread_self()); while (1) { pthread_mutex_lock(&(pool->mutex)); while (pool->queue_size == 0 && !pool->shutdown) { printf("[Debug] Thread 0x%x is waiting\n", (unsigned int) pthread_self()); pthread_cond_wait(&(pool->ready), &(pool->mutex)); } if (pool->shutdown) { pthread_mutex_unlock(&(pool->mutex)); printf("[Debug] Thread 0x%x will exit\n", (unsigned int) pthread_self()); pthread_exit(NULL); } printf("[Debug] Thread 0x%x is starting to work\n", (unsigned int) pthread_self()); assert(pool->queue_size != 0); assert(pool->queue != NULL); --pool->queue_size; thread_worker* worker = pool->queue; pool->queue = worker->next; pthread_mutex_unlock(&(pool->mutex)); printf("[Debug] Start process...\n"); (*(worker->process))(worker->arg); free(worker); } pthread_exit(NULL); } static thread_pool* pool_init(int max_thread) { int i = 0; thread_pool* pool = malloc(1 * sizeof (thread_pool)); pthread_mutex_init(&(pool->mutex), NULL); pthread_cond_init(&(pool->ready), NULL); pool->queue = NULL; pool->max_thread = max_thread; pool->queue_size = 0; pool->shutdown = 0; pool->thread = malloc(max_thread * sizeof (pthread_t)); for (i = 0; i < max_thread; ++i) pthread_create(&(pool->thread[i]), NULL, pool_thread_worker, pool); return pool; } static void pool_destroy(thread_pool* pool) { int i; thread_worker* head = NULL; if (pool->shutdown) return; pool->shutdown = 1; pthread_cond_broadcast(&(pool->ready)); for (i = 0; i < pool->max_thread; ++i) pthread_join (pool->thread[i], NULL); free (pool->thread); while (pool->queue != NULL) { head = pool->queue; pool->queue = pool->queue->next; free(head); } pthread_mutex_destroy(&(pool->mutex)); pthread_cond_destroy(&(pool->ready)); free(pool); } void pool_add_worker(thread_pool* pool, process_func process, void *arg) { thread_worker* worker = malloc(1 * sizeof (thread_worker)); worker->process = process; worker->arg = arg; worker->next = NULL; pthread_mutex_lock(&(pool->mutex)); thread_worker* queue = pool->queue; if (queue == NULL) pool->queue = worker; else { while (queue->next != NULL) queue = queue->next; queue->next = worker; } assert(pool->queue != NULL); ++pool->queue_size; printf("[Debug] Queue size: %i\n", pool->queue_size); pthread_mutex_unlock(&(pool->mutex)); pthread_cond_signal(&(pool->ready)); } static int create_and_bind(char* port) { struct addrinfo hints; struct addrinfo* result; struct addrinfo* rp; int s; int sfd; memset(&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */ hints.ai_socktype = SOCK_STREAM; /* We want a TCP socket */ hints.ai_flags = AI_PASSIVE; /* All interfaces */ if ((s = getaddrinfo(NULL, port, &hints, &result)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); return -1; } for (rp = result; rp != NULL; rp = rp->ai_next) { if ((sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1) continue; if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0) break; close(sfd); } if (rp == NULL) { fprintf(stderr, "Could not bind\n"); return -1; } freeaddrinfo(result); return sfd; } static int make_socket_non_blocking(int sfd) { int flags; flags = fcntl(sfd, F_GETFL, 0); if (flags == -1) { perror("fcntl"); return -1; } flags |= O_NONBLOCK; if (fcntl(sfd, F_SETFL, flags) == -1) { perror("fcntl"); return -1; } return 0; } void add_socket_to_epoll(int sfd, int efd) { struct epoll_event event; if (make_socket_non_blocking(sfd) == -1) abort(); event.data.fd = sfd; event.events = EPOLLIN | EPOLLET; if (epoll_ctl(efd, EPOLL_CTL_ADD, sfd, &event) == -1) { perror("epoll_ctl"); abort(); } } int declare_socket(char* port, int efd) { int sfd; if (((sfd = create_and_bind(port)) == -1)) abort(); add_socket_to_epoll(sfd, efd); if (listen(sfd, SOMAXCONN) == -1) { perror("listen"); abort(); } return sfd; } /* We have a notification on the listening socket, which means one or more incoming connections. */ static void handle_incoming_connection(int sfd, int efd) { while (1) { struct sockaddr in_addr; socklen_t in_len; int infd; char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV]; in_len = sizeof (in_addr); infd = accept(sfd, &in_addr, &in_len); if (infd == -1) { /* We have processed all incoming connections. */ if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) perror("accept"); return; } if (getnameinfo(&in_addr, in_len, hbuf, sizeof hbuf, sbuf, sizeof sbuf, NI_NUMERICHOST | NI_NUMERICSERV) == 0) { printf("Accepted connection on descriptor %d " "(host=%s, port=%s)\n", infd, hbuf, sbuf); } /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */ add_socket_to_epoll(infd, efd); } } static char* handle_command(const char* cmd) { printf("Cmd du client: %s\n", cmd); // Mettre le retour du serveur ou NULL si pas de retour. char* res = calloc(256, sizeof (char)); strncpy(res, "Bonjour du serveur", 256); return res; } /* We have data on the fd waiting to be read. Read and display it. We must read whatever data is available completely, as we are running in edge-triggered mode and won't get a notification again for the same data. */ static void handle_session_socket_read(void* arg) { thread_param* param = arg; unsigned int size = 0; unsigned int limit = 512; char* cmd = calloc(limit, sizeof (char)); char* res = NULL; int stop = 0; while (!stop) { ssize_t count; char buf[512]; count = read(*param->accept_fd, buf, sizeof(buf)); switch (count) { case -1: { /* If errno == EAGAIN, that means we have read all data. So go back to the main loop. */ if (errno != EAGAIN) { perror("read"); return; } stop = 1; break; } case 0: /* End of file. The remote has closed the connection. */ printf("Closed connection on descriptor %d\n", *param->accept_fd); close(*param->accept_fd); epoll_ctl(*(param->epoll_fd), EPOLL_CTL_DEL, *(param->accept_fd), param->ev); --(*param->maxfd); return; default: size += count; if (size > limit) { limit *= 2; cmd = realloc(cmd, limit * sizeof (char)); } strncat(cmd, buf, count); } } res = handle_command(cmd); if (res) { write(*param->accept_fd, res, strlen(res)); free(res); } free(cmd); } static void event_loop(thread_pool* pool, struct epoll_event* events, int* sfds, int efd, int maxfd) { while (1) { int i = 0; int n = epoll_wait(efd, events, maxfd, -1); for (i = 0; i < n; ++i) { if ((events[i].events & EPOLLERR) || (events[i].events & EPOLLHUP) || (!(events[i].events & EPOLLIN))) { /* An error has occured on this fd, or the socket is not ready for reading (why were we notified then?) */ fprintf(stderr, "epoll error\n"); close(events[i].data.fd); } else if (is_in_tab(events[i].data.fd, sfds)) handle_incoming_connection(events[i].data.fd, efd); else { thread_param* param = malloc(1 * sizeof (thread_param)); param->epoll_fd = &efd; param->accept_fd = &events[i].data.fd; param->ev = &events[i]; param->maxfd = &maxfd; pool_add_worker(pool, &handle_session_socket_read, param); } } } } int main(int argc, char* argv[]) { int maxfd = 10; int sfd[65535] = {0}; int efd; int i = 0; struct epoll_event* events; if (argc < 2) { fprintf(stderr, "Usage: %s port1 port2 etc...\n", argv[0]); exit(0); } thread_pool* pool = pool_init(sysconf(_SC_NPROCESSORS_ONLN )); if ((efd = epoll_create1(0)) == -1) { perror("epoll_create"); abort(); } for (i = 1; i < argc && i < 65535; ++i) sfd[i - 1] = declare_socket(argv[i], efd); events = calloc(maxfd, sizeof (struct epoll_event)); event_loop(pool, events, sfd, efd, maxfd); pool_destroy(pool); free(events); for (i = 1; i < argc && i < 65535; ++i) close(sfd[i - 1]); return 0; }
Améliorez votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature
/*
SERVEUR PROXY-CACHE
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include "constante.h"
#define NB_MAX_COEURS_PROC 8
#define NB_MAX_CLIENTS_SIMULTANNES 10
#define TAILLE_MAX_PILE_CLIENTS NB_MAX_CLIENTS_SIMULTANNES
#define TAILLE_REQUETE 1024
typedef struct PileClients
{
int i;
int pile[TAILLE_MAX_PILE_CLIENTS];
}PileClients;
//var globales
PileClients pile;
int lectureSockComClient(int sock_com, char *requeteClient)
{
//----------------------------------------------------------------------------------
// Phase d'échange - Lecture Sock
//----------------------------------------------------------------------------------
if(read(sock_com, requeteClient, strlen(requeteClient)) == -1)
{
perror(">> Erreur : Probleme de lecture de la socket.\n");
return 0;
}
return 1;
}
int ecritureSockComClient(int sock_com, char *reponseClient)
{
//----------------------------------------------------------------------------------
// Phase d'échange - Ecriture Sock
//----------------------------------------------------------------------------------
if(write(sock_com, reponseClient, strlen(reponseClient)) == -1)
{
perror(">> Erreur : Il y a un probleme dans l'envoi de la réponse au client\n");
return 0;
}
return 1;
}
int traitementRequeteClient(char *requeteClient, char *reponseClient)
{
//TO DO
return 1;
}
void *thread_GestionClient(void *arg)
{
while(1)
{
//récup des info dans la pile de tâche quand le signal est reçu
pthread_mutex_lock(&mutex1);
pthread_cond_wait(&cond1, &mutex1);//attend le signal - relâche le verrou jusqu'a la reception d'un signal
int sock_com = pile.pile[pile.i];
pile.i--;
pthread_mutex_unlock(&mutex1);
//réception et traitement de la requête client
//lecture de la requete
char requeteClient[TAILLE_REQUETE] = "";
if(lectureSockComClient(sock_com, requeteClient) == 1)
{
printf("%s\n", requeteClient);
//traitement de la requete si elle a été lu correctement
char reponseClient[TAILLE_REQUETE] = "";
if(traitementRequeteClient(requeteClient, reponseClient) == 1)
{
strcpy(reponseClient, "salut");//pour test
//on envoit la requete réponse au client
if(ecritureSockComClient(sock_com, reponseClient) == 1)
printf("Réponse pour le client :\n%s\n", reponseClient);
}
}
//on ferme la socket de comunication
close((int) sock_com);
}
}
int main()
{
printf("### Début prgm ServeurProxy ###\n\n");
//initialisation struct PileClients pour les threads
pile.i = -1;
pthread_t thread_clients[NB_MAX_COEURS_PROC];
pthread_cond_init(&cond1, NULL);
//création des threads qui s'occuperont de gérer les requêtes des clients
int i;
for(i=0 ; i<sysconf(_SC_NPROCESSORS_ONLN) ; i++)//sysconf(_SC_NPROCESSORS_ONLN) retourne le nombre de coeurs dispo et actif sur le système
if(pthread_create(&thread_clients[i], NULL, thread_GestionClient, (void*) i) != 0)//si la création a foiré : renvoit != 0
perror(">> Erreur de creation du thread\n");
//écoute des connexions TCP sur le port 80
while(1)
{
int sock;
struct sockaddr_in adresse;
u_short port = 80;
//ouverture d'une socket
sock = socket(AF_INET, SOCK_STREAM, 0);//SOCK_STREAM = TCP / SOCK_DGRAM = UDP
if(sock < 0)
perror(">> Erreur d'ouverture de la socket");
else
{
//affectation de l'adresse a la structure
adresse.sin_family = AF_INET;//AF_INET = internet (TCP/IP)
adresse.sin_port = htons((u_short)port);//La fonction htonl() convertit l'entier non signé hostlong depuis l'ordre des octets de l'hôte vers celui du réseau (which is big-endian).
adresse.sin_addr.s_addr = htonl(INADDR_ANY);// = prêt à recevoir de n'importe quel clients.
//pour permettre de réutiliser une socket existante
int options = -1;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &options, sizeof (options));
//association de la socket a l'adresse local
if(bind(sock, (struct sockaddr *) &adresse, sizeof(adresse)) != 0)
perror(">> Erreur d'association");
else
{
//----------------------------------------------------------------------------------
// Phase de connexion
//----------------------------------------------------------------------------------
//attente de connexions client
printf("Serveur en attente d'une connexion ...\n\n");
if(listen(sock, NB_MAX_CLIENTS_SIMULTANNES) != 0)
perror(">> Erreur de la fonction Listen");
else
{
while(1)
{
//Acceptation de la connexion
int sock_com = accept(sock, (struct sockaddr *) 0, (int *) 0);
if(sock_com == -1)
perror(">> Erreur de la fct Accept");
else
{
printf("...CONNEXION ETABLIE...\n\n");
//on ajoute le nouveau client à la pile de tâche
pthread_mutex_lock(&mutex1);
pile.i++;
pile.pile[pile.i] = sock_com;
pthread_mutex_unlock(&mutex1);
pthread_cond_signal(&cond1);//envoie le signal mais ne reveil qu'un seul wait();
}
}
}
}
}
}
}
Sauf que j'aurai une question : comment aller récupérer la page que le client désire depuis mon proxy ?Ton serveur possède des clients, mais rien l'empêche d'être lui même client d'un autre serveur. Pour cela, tu va devoir implémenter un code semblable à un client au sein de ton serveur.
Ca voudrait dire qu'il faut décortiquer la requête reçue par le client pour trouver où se co...Si tu veux gérer de l'HTTP à la main, oui il va falloir décortiquer les requêtes et gérer le protocole entièrement toi même !
Améliorez votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature
Améliorez votre expérience CodeS-SourceS avec ce plugin:
http://codes-sources.commentcamarche.net/forum/affich-10000111-plugin-better-cs-2#cptpingu-signature