Browse Source

sockets handle

test
nicolas-arnaud 2 years ago
parent
commit
7aaa3521b7
  1. 23
      Makefile
  2. 12
      conf.d/default.conf
  3. 129
      srcs/server.cpp
  4. 25
      srcs/server.hpp
  5. 25
      srcs/tools.cpp

23
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

12
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;
}
}

129
srcs/server.cpp

@ -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);
}

25
srcs/server.hpp

@ -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);

25
srcs/tools.cpp

@ -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…
Cancel
Save