gusucode.com > 它是一个c_s网络编程框架源码程序 > st_asio_wrapper/performance_test/asio_client/asio_client.cpp

    
#include <boost/interprocess/detail/atomic.hpp>
using namespace boost::interprocess::ipcdetail;

//configuration
#define SERVER_PORT		9527
//configuration

#include "../../include/st_asio_wrapper_client.h"
using namespace st_asio_wrapper;

#ifdef _MSC_VER
#define atoll _atoi64
#endif

#define QUIT_COMMAND	"quit"

size_t msg_num = 1024;
size_t msg_len = 1024; //must greater than or equal to sizeof(size_t)
char msg_fill = '0';

boost::uint32_t completed_client_num;

class client : public st_client
{
public:
	client() : recv_seq(0), recv_data_num(0) {}
	inline size_t get_recv_data_num() const {return recv_data_num;}

protected:
	//msg handling: send the original msg back(echo server)
#ifndef FORCE_TO_USE_MSG_RECV_BUFFER //not force to use msg recv buffer(so on_msg() will make the decision)
	//we can handle the msg very fast, so we don't use the recv buffer(return false)
	virtual bool on_msg(const std::string& str) {handle_msg(str); return false;}
#endif
	//msg handling end

private:
	void handle_msg(const std::string& str)
	{
		if (++recv_seq == msg_num) //client data->server->client finish
			atomic_inc32(&completed_client_num);

		//simply check the recv data's correctness
		if (msg_len != str.size())
			printf("wrong length: %lu.\n", str.size());

		if (memcmp(&recv_seq, str.data(), sizeof(size_t)))
			printf("wrong recv seq: %lu/%lu.\n", recv_seq, *(size_t*) str.data());

		recv_data_num += str.size();
	}

private:
	size_t recv_seq;
	size_t recv_data_num;
};

int client_num = 8;
int main(int argc, const char* argv[]) {
	///////////////////////////////////////////////////////////////////////
	puts("usage: asio_client client_num msg_num msg_len msg_fill");
	//use 'client_num' clients, send and recv 'msg_num' msgs,
	//which is 'msg_len' characters long, and filled with 'msg_fill'

	if (argc > 1) client_num = std::min(256, std::max(atoi(argv[1]), 1));
	if (argc > 2) msg_num = std::max((size_t) atoll(argv[2]), (size_t) 1);
	//if use custom packer, change here to work out the right max msg length, which is not include all the
	//extra data(for example: header) added by packer, here is MAX_MSG_LEN - HEAD_LEN for the default packer
	if (argc > 3) msg_len = std::min((size_t) (MAX_MSG_LEN - HEAD_LEN),
		std::max((size_t) atoll(argv[3]), sizeof(size_t))); //include seq, see client::recv_seq
	if (argc > 4) msg_fill = argv[4][0];

	printf("exec: asio_client %d %lu %lu %c\n", client_num, msg_num, msg_len, msg_fill);
	puts("performance test begin, this application will has no response during the test!");
	///////////////////////////////////////////////////////////////////////

	auto clients = new client[client_num];
	for (auto i = 0; i < client_num; ++i)
	{
//		clients[i].set_server_addr(SERVER_PORT, "::1"); //ipv6
//		clients[i].set_server_addr(SERVER_PORT, "127.0.0.1"); //ipv4
		clients[i].start_service();
	}
	this_thread::yield();

	unsigned percent = 0;
	auto total_data_num = msg_num * msg_len * client_num;
	auto begin_time = get_system_time().time_of_day().total_seconds();
	auto buff = new char[msg_len];
	memset(buff, msg_fill, msg_len);
	for (size_t i = 1; i <= msg_num; ++i)
	{
		size_t recv_data_num = 0;

		memcpy(buff, &i, sizeof(size_t)); //seq
		for (auto i = 0; i < client_num; ++i)
		{
			while (!clients[i].send_msg(buff, msg_len)) //send buffer overflow
				this_thread::sleep(get_system_time() + posix_time::milliseconds(50));

			recv_data_num += clients[i].get_recv_data_num();
		}

		unsigned new_percent = (unsigned) (100 * recv_data_num / total_data_num);
		if (percent != new_percent)
		{
			percent = new_percent;
			printf("\r%u%%", percent);
			fflush(stdout);
		}
	}
	delete[] buff;

	while(atomic_read32(&completed_client_num) != (unsigned) client_num)
		this_thread::sleep(get_system_time() + posix_time::milliseconds(50));

	auto used_time = get_system_time().time_of_day().total_seconds() - begin_time;
	printf("\r100%%\ntime spent statistics: %d hours, %d minutes, %d seconds.\n",
		used_time / 60 / 60, (used_time / 60) % 60, used_time % 60);
	if (used_time > 0)
		printf("speed: %lu(*2)kB/s.\n", total_data_num / 1024 / used_time);

	for (auto i = 0; i < client_num; ++i)
		clients[i].stop_service();
	delete[] clients;

	return 0;
}

//restore configuration
#undef SERVER_PORT
//restore configuration