summaryrefslogtreecommitdiff
path: root/tags/START/glagen/algo_distribue/network/Server.hh
diff options
context:
space:
mode:
Diffstat (limited to 'tags/START/glagen/algo_distribue/network/Server.hh')
-rw-r--r--tags/START/glagen/algo_distribue/network/Server.hh218
1 files changed, 218 insertions, 0 deletions
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 <list>
+#include <iostream>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <signal.h>
+#include <poll.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <assert.h>
+#include "data/Data.hh"
+
+extern char gl_handle;
+
+extern void signal_alarm(int);
+
+template<class TYPEDATA> 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<int>;
+ 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<int> 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<int>::const_iterator fd_client_tmp;
+ std::list<int>::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<int>& list_fd) // retourne la liste des files descriptors a lire
+ {
+ struct pollfd poll_fd[_fd_client->size()];
+ std::list<int>::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<class TYPEDATA>
+ void send_data(const int& fd, const Data<TYPEDATA>& data)
+ {
+ data.send(fd);
+ }
+
+ template<class TYPEDATA>
+ void send_data(const Data<TYPEDATA>& data,
+ const std::list<int>& fd_client)
+ {
+ std::list<int>::const_iterator fd = fd_client.begin();
+ for (; fd != fd_client.end(); ++fd)
+ data.send(*fd);
+ }
+
+ template<class TYPEDATA>
+ void received_data(Data<TYPEDATA>& data, const std::list<int>& fd_client)
+ {
+ std::list<int>::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<int>* get_list_fd() const { return (_fd_client); }
+
+ unsigned int get_nb_client() const { return (_fd_client->size()); }
+
+private:
+ std::list<int> *_fd_client;
+ struct sockaddr_in *_sock_in;
+ int _port;
+ unsigned int _client_max;
+ int _fd;
+};
+
+#endif // SERVER_HH_