int Server::start() { epoll_event * e = new epoll_event[1000]; if (e == NULL) return -1; for (;;) { int nfd, l_ret; nfd = epoll_wait(m_epfd, e, 1000, -1); //printf("nfd: %i %d\n", nfd, m_ready); for (int i = 0; i < nfd ; i++) { if (e[i].data.fd == m_ServerConn.getSocketFd()) // new connection { if (m_servers_connected < m_servers_total || m_servers_total == -1) { TcpConnection * temp = m_ServerConn.accept(); if (temp != NULL) { int fd = temp->getSocketFd(); m_Clients[fd] = temp; this->setnonblock(fd); // @ todo check for errors if( this->addHandler(fd, EPOLLIN|EPOLLET|EPOLLRDHUP, temp) != 0 ) { printf("SERVER ERROR:\t Failed connecting to client.\n"); // @ todo -- attempt recovery return -1; } else { printf("SERVER STATUS:\t A client connected.\n"); m_servers_connected += 1; if ((l_ret = this->handleNewConnection(fd)) < 0) return l_ret; if (m_servers_total != -1 && m_servers_connected == m_servers_total) { m_ready = true; if ((l_ret = this->allConnectionReadyHandler()) < 0) return l_ret; } } } } else { } } else { if (e[i].events & EPOLLRDHUP || e[i].events & EPOLLHUP || e[i].events & EPOLLERR) { printf("SERVER WARNING:\t Client Hangup/Error\n"); handle_epoll(m_epfd, EPOLL_CTL_DEL,e[i].data.fd, NULL); // @todo add error checking continue; } else if (e[i].events & EPOLLIN) { if (m_ready) { int ret = handler(e[i].data.fd); if (ret < 0) { if (handle_epoll(m_epfd, EPOLL_CTL_DEL,e[i].data.fd, NULL) != 0) { return -1; } } } else { printf("SERVER ERROR:\t Not handleing because not all clients connected\n"); } } } if( modifyHandler(e[i].data.fd, EPOLLET|EPOLLIN|EPOLLHUP ) == -1) { DEBUGPRINT("SERVER ERROR:\t Could not add handler to TCP Connection\n"); return -1; } } } delete [] e; return 0; }
int Network::Server::initConnection(const char* host, const char* port) { if (strlen(host) > INET6_ADDRSTRLEN || strlen(port) > MAX_PORT_LENGTH ) { DEBUGPRINT("SERVER ERROR:\t Invalid port or host length to init\n"); return -2; } if (host == NULL || port == NULL) { DEBUGPRINT("SERVER ERROR:\t Invalid arguments to init\n"); } LOGPRINT("SERVER STATUS:\t Connection to host:%s:%s\n", host, port); addrinfo l_hints, *l_result, *l_p; int l_resvalue = -1; memset(&l_hints, 0, sizeof(struct addrinfo) ); l_hints.ai_family = AF_UNSPEC; l_hints.ai_socktype = SOCK_STREAM; if ((l_resvalue = getaddrinfo(host, port, &l_hints, &l_result)) == -1) { DEBUGPRINT("SERVER ERROR:\t Could not get addrinfo: %s\n", gai_strerror(l_resvalue)); return -1; } TcpConnection * conn = new TcpConnection(); if (conn == NULL) { DEBUGPRINT("SERVER ERROR:\t Could not create new TCP Connection\n"); return -1; } for (l_p = l_result; l_p != NULL; l_p = l_p->ai_next) { if ((l_resvalue =conn->socket(l_p)) != 0) { if (l_resvalue == -1) { DEBUGPRINT("SERVER ERROR:\t Could not connect socket trying next\n"); } else if (l_resvalue == -2) { DEBUGPRINT("SERVER ERROR:\t Argument error to socket\n"); } else { DEBUGPRINT("SERVER ERROR:\t Invalid Return\n"); } continue; } if ((l_resvalue = conn->connect(l_p)) != 0) { if (l_resvalue == -1) { DEBUGPRINT("SERVER ERROR:\t Could not connect to server/port\n"); } else if (l_resvalue == -2) { DEBUGPRINT("SERVER ERROR:\t Argument error to connect\n"); } else { DEBUGPRINT("SERVER ERROR:\t Invalid return\n"); } conn->close(); continue; } break; } if (l_p == NULL) { DEBUGPRINT("SERVER FAILURE:\t Failed to connect to %s:%s\n", host, port); return -1; } int fileDesc = conn->getSocketFd(); int enable = 1; if (setsockopt(fileDesc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == -1) { return -1; } if ( setnonblock(fileDesc) == -1) { DEBUGPRINT("SERVER ERROR:\t Could not set socket to non-blocking\n"); } if( addHandler(fileDesc, EPOLLET|EPOLLIN|EPOLLHUP, conn ) == -1) { DEBUGPRINT("SERVER ERROR:\t Could not add handler to tcpConnection\n"); return -1; } return fileDesc; }