nicolas-arnaud
2 years ago
5 changed files with 214 additions and 0 deletions
@ -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 |
||||
|
|
||||
|
|
@ -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; |
||||
|
} |
||||
|
} |
@ -0,0 +1,129 @@ |
|||||
|
/**
|
||||
|
Handle multiple socket connections with select and fd_set on Linux |
||||
|
*/ |
||||
|
|
||||
|
#include <iostream> |
||||
|
|
||||
|
#include <fcntl.h> |
||||
|
#include <stdio.h> |
||||
|
#include <string.h> //strlen |
||||
|
#include <stdlib.h> |
||||
|
#include <errno.h> |
||||
|
#include <unistd.h> //close |
||||
|
#include <arpa/inet.h> //close |
||||
|
#include <sys/types.h> |
||||
|
#include <sys/socket.h> |
||||
|
#include <netinet/in.h> |
||||
|
#include <sys/time.h> //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); |
||||
|
} |
@ -0,0 +1,25 @@ |
|||||
|
/* ************************************************************************** */ |
||||
|
/* */ |
||||
|
/* ::: :::::::: */ |
||||
|
/* server.hpp :+: :+: :+: */ |
||||
|
/* +:+ +:+ +:+ */ |
||||
|
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
||||
|
/* +#+#+#+#+#+ +#+ */ |
||||
|
/* Created: 2022/11/02 11:16:17 by narnaud #+# #+# */ |
||||
|
/* Updated: 2022/11/02 12:24:25 by narnaud ### ########.fr */ |
||||
|
/* */ |
||||
|
/* ************************************************************************** */ |
||||
|
#pragma once |
||||
|
|
||||
|
#include <sys/socket.h> |
||||
|
#include <netinet/in.h> |
||||
|
#include <arpa/inet.h> |
||||
|
#include <unistd.h> |
||||
|
|
||||
|
#include <cerrno> |
||||
|
#include <cstring> |
||||
|
#include <fstream> |
||||
|
#include <iostream> |
||||
|
#include <string> |
||||
|
void *ft_memset(void *b, int c, size_t len); |
||||
|
|
@ -0,0 +1,25 @@ |
|||||
|
/* ************************************************************************** */ |
||||
|
/* */ |
||||
|
/* ::: :::::::: */ |
||||
|
/* tools.cpp :+: :+: :+: */ |
||||
|
/* +:+ +:+ +:+ */ |
||||
|
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ |
||||
|
/* +#+#+#+#+#+ +#+ */ |
||||
|
/* Created: 2022/11/02 11:01:55 by narnaud #+# #+# */ |
||||
|
/* Updated: 2022/11/02 11:14:36 by narnaud ### ########.fr */ |
||||
|
/* */ |
||||
|
/* ************************************************************************** */ |
||||
|
|
||||
|
#include <stddef.h> |
||||
|
|
||||
|
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); |
||||
|
} |
Loading…
Reference in new issue