/* net/tcpserver.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #include #include #include #include #include #include #include "sys/sys.h" #include "net/tcpserver.h" #include "net/net.h" namespace net { TCPServer::TCPServer(std::string const host, unsigned int const port) { tcpserver_fd = -1; tcpserver_error = true; con_print << "Initializing network server..." << std::endl; // initialize socket tcpserver_fd = ::socket(PF_INET, SOCK_STREAM, 0); if (tcpserver_fd == -1) { // FIXME error handling con_error << "Network can't create socket!" << std::endl; //perror("socket"); return; } // set socket options socklen_t yes = 1; if (::setsockopt(tcpserver_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(socklen_t)) == -1) { // FIXME error handling std::cerr << "Network can't set socket options!" << std::endl; //perror("setsockopt"); return; } // Get the local adress to bind to struct sockaddr_in listen_addr; listen_addr.sin_family = AF_INET; listen_addr.sin_port = htons(port); //listen_addr.sin_addr.s_addr = htonl(INADDR_ANY); listen_addr.sin_addr.s_addr = inet_addr(host.c_str()); memset(listen_addr.sin_zero, '\0', sizeof(listen_addr.sin_zero)); // bind the local address to the socket ( note the typecast) if (::bind(tcpserver_fd, (struct sockaddr *) &listen_addr, sizeof(struct sockaddr)) == -1) { // FIXME error handling con_error << "Network can't bind to local address!" << std::endl; //perror("bind"); return; } // listen if (::listen(tcpserver_fd, MAXPENDINGCONNECTIONS) == -1) { // FIXME error handling con_error << "Network failed to listen on socket!" << std::endl; //perror("listen"); return; } tcpserver_error = false; con_print << " listening on " << inet_ntoa(listen_addr.sin_addr) << ":" << ntohs(listen_addr.sin_port) << std::endl; } TCPServer::~TCPServer() { if (tcpserver_fd != -1) ::close(tcpserver_fd); //con_debug << "TCPServer: terminated." << std::endl; } bool TCPServer::valid() const { return (tcpserver_fd != -1); } bool TCPServer::invalid() const { return (tcpserver_fd == -1); } bool TCPServer::error() const { return tcpserver_error; } int TCPServer::fd() const { return tcpserver_fd; } void TCPServer::abort() { tcpserver_error = true; } void TCPServer::accept() { //con_debug << "TCPServer: accept()" << std::endl; struct sockaddr_in client_addr; socklen_t addrlen = sizeof(struct sockaddr_in); int clientfd = ::accept(tcpserver_fd, (struct sockaddr *) &client_addr, &addrlen); if (clientfd == -1) { // FIXME error handling con_error << "Network accept() error!" << std::endl; //perror("accept"); return; } else { std::string host(inet_ntoa(client_addr.sin_addr)); int port = client_addr.sin_port; client_connect(clientfd, host, port); } } }