int main(int argc, const char **argv) {
    try {
        if (argc != 5) {
            std::cerr <<
                "Usage: " << argv[0] << " CONNECTION-URL AMQP-ADDRESS MESSAGE-COUNT THREAD-COUNT\n"
                "CONNECTION-URL: connection address, e.g.'amqp://127.0.0.1'\n"
                "AMQP-ADDRESS: AMQP node address, e.g. 'examples'\n"
                "MESSAGE-COUNT: number of messages to send\n"
                "THREAD-COUNT: number of sender/receiver thread pairs\n";
            return 1;
        }

        const char *url = argv[1];
        const char *address = argv[2];
        int n_messages = atoi(argv[3]);
        int n_threads = atoi(argv[4]);
        int count = n_messages * n_threads;

        // Total messages to be received, multiple receiver threads will decrement this.
        std::atomic_int remaining;
        remaining.store(count);

        // Run the proton container
        proton::container container;
        auto container_thread = std::thread([&]() { container.run(); });

        // A single sender and receiver to be shared by all the threads
        sender send(container, url, address);
        receiver recv(container, url, address);

        // Start receiver threads, then sender threads.
        // Starting receivers first gives all receivers a chance to compete for messages.
        std::vector<std::thread> threads;
        threads.reserve(n_threads*2); // Avoid re-allocation once threads are started
        for (int i = 0; i < n_threads; ++i)
            threads.push_back(std::thread([&]() { receive_thread(recv, remaining); }));
        for (int i = 0; i < n_threads; ++i)
            threads.push_back(std::thread([&]() { send_thread(send, n_messages); }));

        // Wait for threads to finish
        for (auto& t : threads) t.join();
        send.close();
        recv.close();
        container_thread.join();
        if (remaining > 0)
            throw std::runtime_error("not all messages were received");
        std::cout << count << " messages sent and received" << std::endl;

        return 0;
    } catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
    }
    return 1;
}
示例#2
0
/*------------------------------------------------------------------------------------------------------------------
-- FUNCTION: main
--
-- DATE: MAR 23 2016
--
-- REVISIONS: MAR 23 2016 - Version 1
--
-- DESIGNER: Spenser Lee
--
-- PROGRAMMER: Spenser Lee
--
-- INTERFACE: int main(int argc, char const *argv[])
--              argc:   number of commandl line arguments
--              argv:   array of command line arguments
--
-- RETURNS: int: success
--
-- NOTES:
-- The entry point for the client program. This function handles accepts and assigns the command line argument for
-- priority. If valid arguments are received, it will attempt to create a message queue, and override default signaling.
-- Then it will prompt the user for a filename through standard input, and send a request message to message queue.
-- It will then create a thread that waits to file messages from the queue.
----------------------------------------------------------------------------------------------------------------------*/
int main(int argc, char *argv[]) {

    struct hostent *hp;
    struct sockaddr_in server;
    struct sockaddr_in local_addr;
    string host;
    string username;
    string message;
    string address;
    char ip[16];
    char **pptr;
    int port;

    if (!proccess_args(&argc, argv, &host, &port, &username, &logactive)) {
        exit(EXIT_FAILURE);
    }

    if (logactive) {
        myfile.open ("log.txt",ios::trunc);
        myfile.close();
        myfile.open ("log.txt",ios::app);
    }

    signal(SIGINT, signal_handler);

    if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        cerr << "Failed to create socket" << endl;
        exit(EXIT_FAILURE);
    }

    memset (&server, 0, sizeof(server));
    server.sin_family   = AF_INET;
    server.sin_port     = htons(port);

    if ((hp = gethostbyname(host.c_str())) == NULL) {
        cerr << "Unknown server address" << endl;
        exit(EXIT_FAILURE);
    }

    memcpy((char *) &server.sin_addr, hp->h_addr, hp->h_length);

    if (connect (sd, (struct sockaddr *)&server, sizeof(server)) == -1) {
        cerr << "Couldn't connect to server" << endl;
        exit(EXIT_FAILURE);
    }
    pptr = hp->h_addr_list;
    cout << "Connected: " <<
            hp->h_name << " " <<
            inet_ntop(hp->h_addrtype, *pptr, ip, sizeof(ip)) << endl;

    thread receive_thread(receive_message);

    socklen_t addr_len = sizeof(local_addr);
    getsockname(sd, (struct sockaddr*)&local_addr, &addr_len);
    address = inet_ntoa( local_addr.sin_addr);

    while (1) {

        getline(cin, message);

        if (username.empty()) {
            message = "[" + get_time() + "] " + address + ": " + message;
        } else {
            message = "[" + get_time() + "] " + address + " (" + username + "): " + message;
        }

        if (message.length() <= BUFLEN) {
            send (sd, message.c_str(), BUFLEN, 0);
            if(logactive){
                myfile<<message.c_str()<<endl;
            }
        } else {
            cout << "Error: message too long" << endl;
        }
    }
}