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";
		}
	}
}
Exemple #2
0
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);
}