From 7aaa3521b7bf4e06163fc10125e09d6f6ab1cf3a Mon Sep 17 00:00:00 2001 From: nicolas-arnaud Date: Sun, 6 Nov 2022 20:54:33 +0100 Subject: [PATCH] sockets handle --- Makefile | 23 ++++++++ conf.d/default.conf | 12 +++++ srcs/server.cpp | 129 ++++++++++++++++++++++++++++++++++++++++++++ srcs/server.hpp | 25 +++++++++ srcs/tools.cpp | 25 +++++++++ 5 files changed, 214 insertions(+) create mode 100644 Makefile create mode 100644 conf.d/default.conf create mode 100644 srcs/server.cpp create mode 100644 srcs/server.hpp create mode 100644 srcs/tools.cpp diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9284e55 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +NAME= server +SRCS= srcs/server.cpp srcs/tools.cpp +OBJS= $(SRCS:.cpp=.o) +CXX=c++ +CXXFLAGS= -Wextra -Wall -std=c++98 + + +all : $(NAME) + +$(NAME): $(OBJS) + $(CXX) $(OBJS) -o $(NAME) + +clean: + rm -rf $(OBJS) + +fclean: clean + rm -rf $(NAME) + +re: fclean all + +.PHONY: all clean fclean re + + diff --git a/conf.d/default.conf b/conf.d/default.conf new file mode 100644 index 0000000..948d49f --- /dev/null +++ b/conf.d/default.conf @@ -0,0 +1,12 @@ + +server { + listen 80; + server_name localhost; + + root datas; + location /site { + root datas/website; + index index.html; + try_files $uri /$uri =404; + } +} diff --git a/srcs/server.cpp b/srcs/server.cpp new file mode 100644 index 0000000..65262a6 --- /dev/null +++ b/srcs/server.cpp @@ -0,0 +1,129 @@ +/** + Handle multiple socket connections with select and fd_set on Linux +*/ + +#include + +#include +#include +#include //strlen +#include +#include +#include //close +#include //close +#include +#include +#include +#include //FD_SET, FD_ISSET, FD_ZERO macros + +#define PORT 80 + +int main(void) +{ + int opt = 1; + int master_socket, addrlen, new_socket, client_socket[30], max_clients = 30, activity, i, valread, sd; + int max_sd; + struct sockaddr_in address; + + char buffer[30000]; + + fd_set readfds; + + char _404[72] = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 4\n\n404!"; + + for (i = 0; i < max_clients; i++) client_socket[i] = 0; + + if( (master_socket = socket(AF_INET, SOCK_STREAM, 0)) == 0) + { + std::cout << std::strerror(errno) << std::endl; + exit(EXIT_FAILURE); + } + + if( setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ) + { + std::cout << std::strerror(errno) << std::endl; + exit(EXIT_FAILURE); + } + + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons( PORT ); + + if (bind(master_socket, (struct sockaddr *)&address, sizeof(address))<0) + { + std::cout << std::strerror(errno) << std::endl; + exit(EXIT_FAILURE); + } + std::cout << "Listener on port " << PORT << std::endl; + + if (listen(master_socket, 3) < 0) + { + std::cout << std::strerror(errno) << std::endl; + exit(EXIT_FAILURE); + } + + addrlen = sizeof(address); + std::cout << "Waiting for connections ..." << std::endl; + + while(1) + { + FD_ZERO(&readfds); + FD_SET(master_socket, &readfds); + max_sd = master_socket; + + for ( i = 0 ; i < max_clients ; i++) + { + sd = client_socket[i]; + if(sd > 0) FD_SET( sd, &readfds); + if(sd > max_sd) max_sd = sd; + } + + activity = select( max_sd + 1, &readfds, NULL, NULL, NULL); + + if ((activity < 0) && (errno!=EINTR)) + std::cout << std::strerror(errno) << std::endl; + + if (FD_ISSET(master_socket, &readfds)) + { + if ((new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) + { + std::cout << std::strerror(errno) << std::endl; + exit(EXIT_FAILURE); + } + fcntl(new_socket, F_GETNOSIGPIPE); + + std::cout << "New connection, socket fd is " << new_socket \ + << ", ip is : " << inet_ntoa(address.sin_addr) \ + << ", port : " << ntohs(address.sin_port) << std::endl; + + for (i = 0; i < max_clients; i++) + { + if( client_socket[i] == 0 ) + { + client_socket[i] = new_socket; + std::cout << "Adding to list of sockets as " << i << std::endl; + break; + } + } + } + + for (i = 0; i < max_clients; i++) + { + sd = client_socket[i]; + if (FD_ISSET( sd, &readfds)) + { + valread = read(sd, buffer,30000); + if (valread == 0) + { + getpeername(sd, (struct sockaddr*)&address, (socklen_t*)&addrlen); + std::cout << "Host disconnected, ip " << inet_ntoa(address.sin_addr)\ + << ", port " << ntohs(address.sin_port) << std::endl; + close( sd ); + client_socket[i] = 0; + } + else send(sd, _404, strlen(_404), 0); + } + } + } + return (0); +} diff --git a/srcs/server.hpp b/srcs/server.hpp new file mode 100644 index 0000000..785da50 --- /dev/null +++ b/srcs/server.hpp @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* server.hpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: narnaud +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2022/11/02 11:16:17 by narnaud #+# #+# */ +/* Updated: 2022/11/02 12:24:25 by narnaud ### ########.fr */ +/* */ +/* ************************************************************************** */ +#pragma once + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +void *ft_memset(void *b, int c, size_t len); + diff --git a/srcs/tools.cpp b/srcs/tools.cpp new file mode 100644 index 0000000..f29945d --- /dev/null +++ b/srcs/tools.cpp @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* tools.cpp :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: narnaud +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2022/11/02 11:01:55 by narnaud #+# #+# */ +/* Updated: 2022/11/02 11:14:36 by narnaud ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include + +void *ft_memset(void *b, int c, size_t len) +{ + size_t i; + unsigned char * b_cpy; + + b_cpy = (unsigned char *)b; + i = 0; + while (i < len) + *(unsigned char *)(b_cpy + i++) = (unsigned char)c; + return ((void *)b); +}