Увеличить asio tcp с резьбой.Ждать нового образца? - PullRequest
0 голосов
/ 25 апреля 2018

У меня есть приложение, которое отправляет структуру в виде сериализованных данных, используя boost asio.

Это все работает хорошо, но я думаю, что я запускаю его неэффективно.Фактические данные, которые я отправляю, обновляются только каждые 30 мс или около того, но как для функций отправки, так и для получения я выполняю цикл, который занимает менее 1 мс.

Это означает, что я отправляю одни и те же данные несколько раз.

Мой вопрос:

Как я могу сделать этот подход более эффективным?

IМожно легко добавить условие_ссылки в функцию отправки для ожидания нового образца, но можно ли заставить получающую сторону ожидать нового образца отправлено ?

Функция отправки:

    void Connection()
    {
        static auto const flags = boost::archive::no_header | boost::archive::no_tracking;

        while(true)
        {
            boost::asio::io_service ios;
            boost::asio::ip::tcp::endpoint endpoint
                = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 4444);
            boost::asio::ip::tcp::acceptor acceptor(ios, endpoint);
            boost::asio::ip::tcp::iostream stream;


            // program stops here until client connects.
            acceptor.accept(*stream.rdbuf());

            connected = true;
            // Send 
            while (connected == true)
            {               
                    try
                    {
                        stream.flush();

                        boost::archive::binary_oarchive archive(stream);
                        archive << data_out; //data_out is my struct, serialized. It is updated and filled in a mutex every 30ms or so.

                    }
                    catch (...) {
                        std::cout << "connection lost, reconnecting..." << std::endl;
                        connected = false;
                    }

                    std::this_thread::sleep_for(std::chrono::milliseconds(1));


            }
        }
    }
}

Функция приема на другом конце:

void Connect()
{

    while (true)
    {
        do {        
            stream.clear();
            stream.connect("127.0.0.1", "4444");

            std::this_thread::sleep_for(std::chrono::milliseconds(100));
        } while (!stream);

        bConnected = true;

        while (bConnected == true && ShutdownRequested == false)
        {
            try
            {
                stream.flush();
                boost::archive::binary_iarchive archive(stream);
                archive >> data_in; //to a struct

         }

}

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Маленькая программа для чтения данных из сокета как можно быстрее

int main()
{
    boost::asio::io_service io_service;

    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3001));

    tcp::socket socket(io_service);
    acceptor.accept(socket);

    for (;;)
    {
        char mybuffer[1256];
        int len = socket.read_some(boost::asio::buffer(mybuffer,1256));
        mybuffer[len] = '\0';
        std::cout << mybuffer;

    }

  return 0;
}
0 голосов
/ 26 апреля 2018

Я не уверен, как это сделать, используя класс iostream, но вместо этого используя класс socket, вы просто вызываете receive или read, чтобы заблокировать, пока байты не будут обнаружены в сети (или async_* вариантов этих звонков, если вы не хотите блокировать).

Если ваша структура данных имеет фиксированную длину, вы можете просто вызвать read с вашим размером структуры в качестве ожидаемого количества байтов для получения.Если это переменная длина, есть немного больше обработки, чтобы сделать.Вы можете добавить ожидаемый размер в качестве первых нескольких байтов в вашей полезной нагрузке и вызывать receive в цикле до тех пор, пока не будет получено это количество байтов.

В документации для буста есть хорошие примеры, если вы еще не проверилиих еще.Я бы рекомендовал посмотреть примеры Chat и Echo .

...