diff --git a/srcs/Webserv.cpp b/srcs/Webserv.cpp index ed33b11..8bd7259 100644 --- a/srcs/Webserv.cpp +++ b/srcs/Webserv.cpp @@ -4,11 +4,11 @@ Webserv::Webserv() { std::cout << "Server init\n"; - // _socket_fd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); - _socket_fd = ::socket(AF_INET, SOCK_STREAM, 0); + _socket_fd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); + //_socket_fd = ::socket(AF_INET, SOCK_STREAM, 0); if (_socket_fd == -1) { - ::perror("err socket(): "); + std::perror("err socket(): "); throw std::runtime_error("Socket init"); } } @@ -37,13 +37,14 @@ void Webserv::bind(in_port_t port) // const struct sockaddr* cast_test = static_cast(addr); struct sockaddr_in addr; + std::memset(&addr, 0, sizeof addr); addr.sin_family = AF_INET; addr.sin_port = ::htons(port); addr.sin_addr.s_addr = ::htonl(INADDR_ANY); // htonl useless with 0 value (INADDR_ANY) ? if (::bind(_socket_fd, (const sockaddr*)&addr, sizeof addr) == -1) { - ::perror("err bind(): "); + std::perror("err bind(): "); throw std::runtime_error("Socket bind"); } } @@ -52,7 +53,7 @@ void Webserv::listen(unsigned int max_connections) { if (::listen(_socket_fd, max_connections) == -1) { - ::perror("err listen(): "); + std::perror("err listen(): "); throw std::runtime_error("Socket listen"); } } @@ -66,53 +67,93 @@ void Webserv::start() struct sockaddr_in addr; socklen_t addr_len; int accepted_fd; - struct pollfd poll_s; - char buf[BUFSIZE]; // WIP buffer. need to try with std::vector or std::string. + char buf[BUFSIZE+1]; // WIP buffer. need to try with std::vector or std::string. int ret; + int timeout = 3000; + int i = 1; + int nfds = 1; + int ret_nfds; + + _poll_s[0].fd = _socket_fd; + _poll_s[0].events = POLLIN; + std::cout << "Server started\n"; - while (1) + int i_loop = 0; + ++i_loop; + std::cout << i_loop << "----------\n"; + std::cout << "loop poll()\n"; + while ( (ret_nfds = ::poll(_poll_s, nfds, timeout)) != -1) { - std::cout << "----------\n"; - std::cout << "accept()\n"; - addr_len = sizeof addr; - accepted_fd = ::accept(_socket_fd, (sockaddr*)&addr, &addr_len); - if (accepted_fd == -1) + i = 1; + while (i < nfds) { - ::perror("err accept(): "); - continue; + if (ret_nfds == 0) + { + std::cout << "timeout\n"; + ::close(_poll_s[i].fd); + _poll_s[i].fd = -1; + --nfds; + } + + else if (_poll_s[i].revents & POLLIN) // READ + { + std::cout << "recv()\n"; + ret = ::recv(_poll_s[i].fd, buf, BUFSIZE, 0); + if (ret == -1) + { + std::perror("err recv(): "); + if (::send(_poll_s[i].fd, MSG_BOUNCE, sizeof MSG_BOUNCE - 1, 0) == -1) + std::perror("err send(): "); + + ::close(_poll_s[i].fd); + _poll_s[i].fd = -1; + --nfds; + continue; + } + /* + if (ret == BUFSIZE) + // send error like "request too long" to client + */ + buf[ret] = '\0'; + _poll_s[i].events = POLLOUT; + } + + else if (_poll_s[i].revents & POLLOUT) // WRITE + { + std::cout << "send()\n"; + if (::send(_poll_s[i].fd, buf, ret, 0) == -1) // echo the read + std::perror("err send(): "); + if (::send(_poll_s[i].fd, MSG_TEST, sizeof MSG_TEST - 1, 0) == -1) + std::perror("err send(): "); + + ::close(_poll_s[i].fd); + _poll_s[i].fd = -1; + --nfds; + } + + ++i; } - // "Your server must never block and the client can be bounced properly if necessary". - // NO-Block OK, but how to handle it ? Miss the bouncing part. - ::fcntl(accepted_fd, F_SETFL, O_NONBLOCK); - std::cout << "poll()\n"; // poll (or equivalent) - poll_s.fd = accepted_fd; - poll_s.events = POLLIN; // We need a way to valid POLLOUT and POLLIN at the same time (both, not one of them) - ::poll(&poll_s, 1, -1); - std::cout << "recv()\n"; - ret = ::recv(accepted_fd, buf, BUFSIZE, 0); - if (ret == -1) + if ((_poll_s[0].fd == _socket_fd) && (_poll_s[0].revents & POLLIN)) // ACCEPT { - ::perror("err recv(): "); - if (::send(accepted_fd, MSG_BOUNCE, sizeof MSG_BOUNCE - 1, 0) == -1) - ::perror("err send(): "); - ::close(accepted_fd); - continue; + std::cout << "accept()\n"; + addr_len = sizeof addr; + accepted_fd = ::accept(_socket_fd, (sockaddr*)&addr, &addr_len); + if (accepted_fd == -1) + { + std::perror("err accept(): "); + continue; + } + ::fcntl(accepted_fd, F_SETFL, O_NONBLOCK); + _poll_s[nfds].fd = accepted_fd; + _poll_s[nfds].events = POLLIN; + ++nfds; } - /* - if (ret == BUFSIZE) - // send error like "request too long" to client - */ - buf[ret] = '\0'; - - std::cout << "send()\n"; - if (::send(accepted_fd, buf, ret, 0) == -1) // echo the read - ::perror("err send(): "); - if (::send(accepted_fd, MSG_TEST, sizeof MSG_TEST - 1, 0) == -1) - ::perror("err send(): "); - ::close(accepted_fd); + ++i_loop; + std::cout << i_loop << "----------\n"; + std::cout << "loop poll()\n"; } } diff --git a/srcs/Webserv.hpp b/srcs/Webserv.hpp index 01f87f1..7c3fd4f 100644 --- a/srcs/Webserv.hpp +++ b/srcs/Webserv.hpp @@ -10,6 +10,7 @@ # include # include // close # include // cout, cin +# include // memset # include // socket, accept, listen, send, recv, bind, connect, setsockopt, getsockname # include // sockaddr_in @@ -33,6 +34,7 @@ class Webserv private: int _socket_fd; + struct pollfd _poll_s[42]; // 42 PLACEHOLDER std::map _request; std::map _response;