From 695965a636bddfbafa0e8b8c66bfd3e7efa5d440 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@0f7e0d06-a6f9-0310-a55f-d5f984f55e4c> Date: Thu, 10 Feb 2005 23:10:52 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'START'. git-svn-id: file:///usr/local/opt/svn/repos/glagen@6 0f7e0d06-a6f9-0310-a55f-d5f984f55e4c --- tags/START/glagen/algo_distribue/network/Server.hh | 218 +++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 tags/START/glagen/algo_distribue/network/Server.hh (limited to 'tags/START/glagen/algo_distribue/network/Server.hh') diff --git a/tags/START/glagen/algo_distribue/network/Server.hh b/tags/START/glagen/algo_distribue/network/Server.hh new file mode 100644 index 0000000..fdfecb4 --- /dev/null +++ b/tags/START/glagen/algo_distribue/network/Server.hh @@ -0,0 +1,218 @@ +// Classe Server + +#ifndef SERVER_HH_ +# define SERVER_HH_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "data/Data.hh" + +extern char gl_handle; + +extern void signal_alarm(int); + +template class Data; + +class Server +{ +public: + Server(const int& port, const unsigned int& nb_client_max) + { + _port = port; + _client_max = nb_client_max; + _fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + _sock_in = new struct sockaddr_in; + _sock_in->sin_family = PF_INET; + _sock_in->sin_port = htons(port); + _sock_in->sin_addr.s_addr = INADDR_ANY; + if ((bind(_fd, (struct sockaddr *)_sock_in, sizeof (*_sock_in)) == -1) + || (listen(_fd, 5) == -1)) + this->error(); + std::cout << "Server started. Listening on port " << _port << std::endl; + _fd_client = new std::list; + this->start_signal(); + this->start(); + } + + void start() + { + int fd_client; + socklen_t len; + struct sockaddr_in sock_client; + + len = sizeof (struct sockaddr_in); + while (gl_handle != -1 && this->_fd_client->size() < _client_max) + { + fd_client = 0; + if ((fd_client = accept(this->_fd, + (struct sockaddr *)&(sock_client), &len)) > 0) + gl_handle = gl_handle | 2; + std::list list_fd; + if (2 == (gl_handle & 2)) + { + this->accept_client(fd_client); + this->send_signal(fd_client); + std::cout << "Number of connected clients :" + << this->_fd_client->size() << std::endl; + } + gl_handle = 0; + this->test_client(); + } + } + + void test_client() + { + if (_fd_client->size()) + { + std::list::const_iterator fd_client_tmp; + std::list::const_iterator fd_client = _fd_client->begin(); + int i = 0; + while (fd_client != _fd_client->end()) + { + i++; + char c = 0; + errno = 0; + fd_client_tmp = fd_client; + read(*fd_client, &c, sizeof(char)); + ++fd_client; + if (errno == 0) + this->remove_client(*fd_client_tmp); + } + } + } + + void error() + { + std::cerr << "Error server : "; + perror(""); + exit(errno); + } + + void remove_client(const int& fd) + { + _fd_client->remove(fd); + std::cout << "Client in the file descriptor : " << fd + << " are disconnected" << std::endl; + std::cout << "Number of connected clients :" + << this->_fd_client->size() << std::endl; + } + + void wait_signal(std::list& list_fd) // retourne la liste des files descriptors a lire + { + struct pollfd poll_fd[_fd_client->size()]; + std::list::const_iterator fd = _fd_client->begin(); + for (int i = 0; fd != _fd_client->end(); ++fd, ++i) + { + poll_fd[i].fd = *fd; + poll_fd[i].events = POLLIN; + } + if (poll(poll_fd, _fd_client->size(), 0) < 0) + assert(0); + for (unsigned int i = 0; i < _fd_client->size(); ++i) + if (poll_fd[i].revents != 0) + { + unsigned char sig = 0; + unsigned int length = 0; + do + { + errno = 0; + length = read(poll_fd[i].fd, &sig, sizeof(unsigned char)); + } + while (errno == 4); + if (errno) + { + perror(""); + exit(errno); + } + if (length == 0) + remove_client(poll_fd[i].fd); + else + if (sig == 42) + { + list_fd.push_back(poll_fd[i].fd); + std::cout << "Reception signal sur le file descriptor :" + << poll_fd[i].fd << std::endl; + } + else + { + std::cout << "Erreur de reception sur le file descriptor :" + << poll_fd[i].fd << std::endl; + exit(2); + } + poll_fd[i].revents = 0; + } + } + + void send_signal(const int& fd) + { + unsigned char sig = 42; + write(fd, &sig, sizeof(unsigned char)); + } + + void start_signal() + { + struct sigaction alarm; + + alarm.sa_handler = signal_alarm; + alarm.sa_flags = 0; + sigemptyset(&(alarm.sa_mask)); + sigaddset(&(alarm.sa_mask), SIGALRM); + sigaction(SIGALRM, &alarm, 0); + ualarm(1, 100000); + } + + template + void send_data(const int& fd, const Data& data) + { + data.send(fd); + } + + template + void send_data(const Data& data, + const std::list& fd_client) + { + std::list::const_iterator fd = fd_client.begin(); + for (; fd != fd_client.end(); ++fd) + data.send(*fd); + } + + template + void received_data(Data& data, const std::list& fd_client) + { + std::list::const_iterator fd = fd_client.begin(); + for (; fd != fd_client.end(); ++fd) + data.receive(*fd); + } + + void accept_client(const int& fd) + { + std::cout << "Client connected on file descriptor: " << fd << std::endl; + _fd_client->push_back(fd); + } + + int get_fd() const { return (_fd); } + + int get_port() const { return (_port); } + + std::list* get_list_fd() const { return (_fd_client); } + + unsigned int get_nb_client() const { return (_fd_client->size()); } + +private: + std::list *_fd_client; + struct sockaddr_in *_sock_in; + int _port; + unsigned int _client_max; + int _fd; +}; + +#endif // SERVER_HH_ -- cgit v1.2.3