mirror of
https://github.com/boostorg/asio.git
synced 2026-01-28 06:42:08 +00:00
Fix compile error in regex overload of async_read_until.hpp. Fixes #5688 Explicitly specify the signal() function from the global namespace. Fixes #5722 Don't read the clock unless the heap is non-empty. Change the SSL buffers sizes so that they're large enough to hold a complete TLS record. Fixes #5854 Make sure the synchronous null_buffers operations obey the user's non_blocking setting. Fixes #5756 Set size of select fd_set at runtime when using Windows. Disable warning due to const qualifier being applied to function type. Fix crash due to gcc_x86_fenced_block that shows up when using the Intel C++ compiler. Fixes #5763 Specialise operations for buffer sequences that are arrays of exactly two buffers. Initialise all OpenSSL algorithms. Fix error mapping when session is gracefully shut down. Various performance improvements: * Split the task_io_service's run and poll code. * Use thread-local operation queues in single-threaded use cases (i.e. concurrency_hint is 1) to eliminate a lock/unlock pair. * Only fence block exit when a handler is being run directly out of the io_service. * Prefer x86 mfence-based fenced block when available. * Use a plain ol' long for the atomic_count when all thread support is disabled. * Allow some epoll_reactor speculative operations to be performed without holding the lock. * Improve locality of reference by performing an epoll_reactor's I/O operation immediately before the corresponding handler is called. This also improves scalability across CPUs when multiple threads are running the io_service. * Pass same error_code variable through to each operation's complete() function. * Optimise creation of and access to the io_service implementation. Remove unused state in HTTP server examples. Add latency test programs. [SVN r74863]
106 lines
3.6 KiB
C++
106 lines
3.6 KiB
C++
//
|
|
// udp_client.cpp
|
|
// ~~~~~~~~~~~~~~
|
|
//
|
|
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
|
|
#include <boost/asio/ip/udp.hpp>
|
|
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
|
#include <algorithm>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <vector>
|
|
#include "high_res_clock.hpp"
|
|
|
|
using boost::asio::ip::udp;
|
|
using boost::posix_time::ptime;
|
|
using boost::posix_time::microsec_clock;
|
|
|
|
const int num_samples = 100000;
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
if (argc != 6)
|
|
{
|
|
std::fprintf(stderr,
|
|
"Usage: udp_client <ip> <port1> "
|
|
"<nports> <bufsize> {spin|block}\n");
|
|
return 1;
|
|
}
|
|
|
|
const char* ip = argv[1];
|
|
unsigned short first_port = static_cast<unsigned short>(std::atoi(argv[2]));
|
|
unsigned short num_ports = static_cast<unsigned short>(std::atoi(argv[3]));
|
|
std::size_t buf_size = static_cast<std::size_t>(std::atoi(argv[4]));
|
|
bool spin = (std::strcmp(argv[5], "spin") == 0);
|
|
|
|
boost::asio::io_service io_service;
|
|
|
|
udp::socket socket(io_service, udp::endpoint(udp::v4(), 0));
|
|
|
|
if (spin)
|
|
{
|
|
udp::socket::non_blocking_io nbio(true);
|
|
socket.io_control(nbio);
|
|
}
|
|
|
|
udp::endpoint target(boost::asio::ip::address::from_string(ip), first_port);
|
|
unsigned short last_port = first_port + num_ports - 1;
|
|
std::vector<unsigned char> write_buf(buf_size);
|
|
std::vector<unsigned char> read_buf(buf_size);
|
|
|
|
ptime start = microsec_clock::universal_time();
|
|
boost::uint64_t start_hr = high_res_clock();
|
|
|
|
boost::uint64_t samples[num_samples];
|
|
for (int i = 0; i < num_samples; ++i)
|
|
{
|
|
boost::uint64_t t = high_res_clock();
|
|
|
|
boost::system::error_code ec;
|
|
socket.send_to(boost::asio::buffer(write_buf), target, 0, ec);
|
|
|
|
do socket.receive(boost::asio::buffer(read_buf), 0, ec);
|
|
while (ec == boost::asio::error::would_block);
|
|
|
|
samples[i] = high_res_clock() - t;
|
|
|
|
if (target.port() == last_port)
|
|
target.port(first_port);
|
|
else
|
|
target.port(target.port() + 1);
|
|
}
|
|
|
|
ptime stop = microsec_clock::universal_time();
|
|
boost::uint64_t stop_hr = high_res_clock();
|
|
boost::uint64_t elapsed_usec = (stop - start).total_microseconds();
|
|
boost::uint64_t elapsed_hr = stop_hr - start_hr;
|
|
double scale = 1.0 * elapsed_usec / elapsed_hr;
|
|
|
|
std::sort(samples, samples + num_samples);
|
|
std::printf(" 0.0%%\t%f\n", samples[0] * scale);
|
|
std::printf(" 0.1%%\t%f\n", samples[num_samples / 1000 - 1] * scale);
|
|
std::printf(" 1.0%%\t%f\n", samples[num_samples / 100 - 1] * scale);
|
|
std::printf(" 10.0%%\t%f\n", samples[num_samples / 10 - 1] * scale);
|
|
std::printf(" 20.0%%\t%f\n", samples[num_samples * 2 / 10 - 1] * scale);
|
|
std::printf(" 30.0%%\t%f\n", samples[num_samples * 3 / 10 - 1] * scale);
|
|
std::printf(" 40.0%%\t%f\n", samples[num_samples * 4 / 10 - 1] * scale);
|
|
std::printf(" 50.0%%\t%f\n", samples[num_samples * 5 / 10 - 1] * scale);
|
|
std::printf(" 60.0%%\t%f\n", samples[num_samples * 6 / 10 - 1] * scale);
|
|
std::printf(" 70.0%%\t%f\n", samples[num_samples * 7 / 10 - 1] * scale);
|
|
std::printf(" 80.0%%\t%f\n", samples[num_samples * 8 / 10 - 1] * scale);
|
|
std::printf(" 90.0%%\t%f\n", samples[num_samples * 9 / 10 - 1] * scale);
|
|
std::printf(" 99.0%%\t%f\n", samples[num_samples * 99 / 100 - 1] * scale);
|
|
std::printf(" 99.9%%\t%f\n", samples[num_samples * 999 / 1000 - 1] * scale);
|
|
std::printf("100.0%%\t%f\n", samples[num_samples - 1] * scale);
|
|
|
|
double total = 0.0;
|
|
for (int i = 0; i < num_samples; ++i) total += samples[i] * scale;
|
|
std::printf(" mean\t%f\n", total / num_samples);
|
|
}
|