void ServerController::start_server() { is_server_running = true; // Create thread for consuming process std::thread consumer_thread(&ServerController::consume_command, this); consumer_thread.detach(); //Create server socket ServerSocket server_socket(port_number); while (true) { try { std::cerr << "Server listening" << "\n"; std::shared_ptr<Socket> socket_client = nullptr; while ((socket_client = server_socket.accept()) != nullptr) { std::thread handler_thread(&ServerController::handle_client, this, socket_client); handler_thread.detach(); std::cerr << "Server listening again" << "\n"; } } catch (const std::exception& ex) { std::cerr << ex.what() << ", resuming..." << "\n"; } } }
void postman::Postman::start() { struct sockaddr_in serv_addr; if ((listen_sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) { ERR("Failed to create socket: %s\n", strerror(errno)); abort(); } DEBUG("Socket Created!\n"); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; // bind errywhere serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(this->listen_port); if ((bind(listen_sock, (struct sockaddr*) &serv_addr, sizeof(serv_addr))) == -1) { ERR("Unable to bind port: %s\n", strerror(errno)); abort(); } DEBUG("Socket bound!\n"); if (listen(listen_sock, 1024) == -1) { ERR("Unable to listen: %s\n", strerror(errno)); abort(); } DEBUG("Socket listening!\n"); while (alive) { DEBUG("Waiting for connection...\n"); int conn; struct sockaddr sockaddr; socklen_t socklen; conn = accept(listen_sock, &sockaddr, &socklen); if (conn == -1) { if (errno == ECONNABORTED) { // We'll get this when the socket is closed DEBUG("Listening thread shutting down...\n"); return; } else { ERR("Accept failed: %s\n", strerror(errno)); abort(); } } DEBUG("Connection recieved!\n"); auto connection_handler = [&sockaddr] (Postman* pmp, int conn_fd) { std::string contents = ""; char buf[4096]; // TODO: dynamically allocate this or be cleverer int read = 0; while ((read = recv(conn_fd, buf, sizeof(buf)-1, 0)) > 0) { contents += buf; memset(buf, 0, sizeof(buf)); if (util::contains(contents, "DONE")) { break; } } struct sockaddr_in sin; memcpy(&sin, &sockaddr, sizeof(struct sockaddr_in)); // HACK HACK HACK postman::Message m(conn_fd, sin, (char *) contents.c_str(), contents.length()); // callback to everyone who has registered with us DEBUG("Message is: %s\n", m.data); for_each(pmp->callbacks.begin(), pmp->callbacks.end(), [&](callback_t cb) { DEBUG("Calling a callback\n"); cb(m); }); DEBUG("Connection closed!\n"); close(conn_fd); }; std::thread handler_thread(connection_handler, this, conn); handler_thread.detach(); } close(listen_sock); }