1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
// Server.cpp
// un comment headers once you are using them.
#include "Conn_Queue.hpp"
#include "Server.hpp"
#include <thread>
#include <unistd.h> // close()
#include <sys/socket.h> // socket(), getaddrinfo(), freeaddrinfo(), bind()
#include <netdb.h> // addrinfo,
#include <cstring> // memset(),
//#include <sys/select.h> // hm...
#include <cstdio> // perror()
#include <cstdlib> // exit()
Server::Server( void(*h)(int&,sockaddr_storage&) , const char* port, bool auto_close = false) {
// m_fd = socket(AF_UNSPEC, SOCK_STREAM, 0);
hndlr = h;
ac = auto_close;
addrinfo hints, *servInfo;
memset(&hints,0,sizeof(hints));
// pack in some hints
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_UNSPEC;
// get, well, addrinfo! lol.
if(getaddrinfo(/* const char *__restrict __name */ NULL , port , &hints , &servInfo) != 0) {
perror("call to getaddrinfo()");
exit(1);
}
// make the socket.
m_fd = socket( servInfo->ai_family , servInfo->ai_socktype , servInfo->ai_protocol );
if(m_fd < 0) {
perror("call to socket()");
exit(1);
}
/*
// make sure you can bind to your port by FORCING IT TO BE SO!! >:) ... just as soon as I figure out how this works.. XD
if (setsockopt(listener,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof yes) == -1) {
perror("an error occured during call to setsockopt()");
exit(1);
}
*/
// bind socket to port
if( bind( m_fd , servInfo->ai_addr , servInfo->ai_addrlen ) != 0 ){
perror("call to bind()");
exit(1);
}
/* just a quick note, NOT FOR SERVER, USE IN CLIENT!!!
if( connect( m_fd , servInfo->ai_addr , servInfo->ai_addrlen ) < 0 ){
perror("an error occured during call to connect()");
exit(1);
}
*/
}
Server::~Server() {
close(m_fd);
}
std::vector<std::thread> Server::start(int pool_size/* = 5 */) {
if(listen( m_fd , 5 ) < 0) {
perror("call to listen()");
exit(1);
}
std::vector<std::thread> ret;
for(int i = 0;i < pool_size;i++)
ret.push_back( std::thread(CONN_HANDLERS::worker_thread, hndlr, &cq, ac) );
ret.push_back( std::thread(CONN_HANDLERS::fill_queue,&cq,m_fd) );
return ret;
}
|