From 8acc060eef3799b0f3f8c7601c67870f553795c7 Mon Sep 17 00:00:00 2001 From: Aki Date: Thu, 30 Apr 2020 21:06:39 +0200 Subject: Made server and client non-blocking --- plop.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/plop.c b/plop.c index eb27125..931618e 100644 --- a/plop.c +++ b/plop.c @@ -1,4 +1,7 @@ +#include +#include #include +#include #include #include #include @@ -35,6 +38,12 @@ int make_server(const char * node, const char * service) if (-1 == server) continue; + if (-1 == fcntl(server, F_SETFL, (fcntl(server, F_GETFL, 0) | O_NONBLOCK))) + { + close(server); + continue; + } + if (0 == bind(server, it->ai_addr,it->ai_addrlen)) break; @@ -56,6 +65,42 @@ int make_server(const char * node, const char * service) return server; } +/// Progresses the connection for a client and shifts it back in the array. +/// `pfd` must be at least `shift_by + 1`-th element of the array. +/// \param pfd Element in array processed by poll +/// \param shift_by Element will be moved by in array this many indices +/// \return Shift value for next handler +/// \see poll(2) +int handle_client(struct pollfd * pfd, const int shift_by) +{ + if (0 == pfd->revents) + { + return shift_by; + } + + if (~(POLLIN | POLLOUT) & pfd->revents) + { + return -1; // TODO: Handle errors properly + } + + static const char * response = + "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain; charset=utf-8\r\n" + "\r\n" + "plop\n"; + + if (-1 == send(pfd->fd, response, strlen(response), 0)) + { + // TODO: Handle errors properly + } + + close(pfd->fd); + (pfd - shift_by)->fd = -1; + (pfd - shift_by)->events = pfd->events; + + return shift_by + 1; +} + /// Standard entry point for the program. /// \param argc Argument count /// \param argv Argument array @@ -67,26 +112,31 @@ int main(int argc, char ** argv) return 4; } - int server = make_server(NULL, argv[1]); + struct pollfd fdv[200]; + memset(fdv, 0, sizeof(fdv)); - int client; - static const char * response = - "HTTP/1.1 200 OK\r\n" - "Content-Type: text/plain; charset=utf-8\r\n" - "\r\n" - "plop\n"; + fdv[0].fd = make_server(NULL, argv[1]); + fdv[0].events = POLLIN; + int fdc = 1; - for (;;) + while (-1 != poll(fdv, fdc, -1)) { - if (-1 != (client = accept(server, NULL, NULL))) + int shift_by = 0; + + for (int i = 1; i < fdc; ++i) + { + shift_by = handle_client(&fdv[i], shift_by); + } + + fdc = fdc - shift_by; + + if (POLLIN == fdv[0].revents) { - if (-1 == send(client, response, strlen(response), 0)) + if (-1 != (fdv[fdc].fd = accept(fdv[0].fd, NULL, NULL))) { - // TODO: Handle errors properly + fdv[fdc].events = POLLIN | POLLOUT; + fdc++; } - - // Ignore the close-related error mess. - close(client); } } } -- cgit v1.1