#ifndef CHILON_POLL_SOCKET_SERVER_HPP
#define CHILON_POLL_SOCKET_SERVER_HPP
#include <chilon/poll/socket_client.hpp>
#include <exception>
namespace chilon { namespace poll {
struct could_not_bind_socket : std::exception {};
struct could_not_listen : std::exception {};
// Server contract:
// void operator()(int socket)
template <class Server>
struct socket_server : public socket_client< socket_server<Server> > {
typedef socket_client< socket_server<Server> > base_t;
void tcp_listen(int const port, int const nListeners) {
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = INADDR_ANY;
if (-1 == bind(base_t::fd_, (struct sockaddr *)&sin, sizeof(sin)))
throw could_not_bind_socket();
if (-1 == listen(base_t::fd_, nListeners))
throw could_not_listen();
}
virtual void operator()(poll_status const) {
// sockaddr addr;
// socklen_t len;
// int newSocket = ::accept(base_t::fd, &addr, &len);
int newSocket = ::accept(base_t::fd_, 0, 0);
if (newSocket == -1) static_cast<Server &>(*this).error();
else {
fcntl(newSocket, F_SETFL, O_NONBLOCK);
static_cast<Server &>(*this).add_client(newSocket);
}
}
socket_server() {}
socket_server(int socket) : base_t(socket) {}
};
} }
#endif