|
|
/*
|
|
|
* Copyright (c) 2016 The ZLToolKit project authors. All Rights Reserved.
|
|
|
*
|
|
|
* This file is part of ZLToolKit(https://github.com/ZLMediaKit/ZLToolKit).
|
|
|
*
|
|
|
* Use of this source code is governed by MIT license that can be found in the
|
|
|
* LICENSE file in the root of the source tree. All contributing project authors
|
|
|
* may be found in the AUTHORS file in the root of the source tree.
|
|
|
*/
|
|
|
|
|
|
#include <csignal>
|
|
|
#include <iostream>
|
|
|
#include "Util/CMD.h"
|
|
|
#include "Util/logger.h"
|
|
|
#include "Util/util.h"
|
|
|
#include "Network/Session.h"
|
|
|
#include "Network/TcpServer.h"
|
|
|
|
|
|
using namespace std;
|
|
|
using namespace toolkit;
|
|
|
|
|
|
/**
|
|
|
* 回显会话
|
|
|
* Echo Session
|
|
|
|
|
|
* [AUTO-TRANSLATED:bc2a4e9e]
|
|
|
*/
|
|
|
class EchoSession : public Session {
|
|
|
public:
|
|
|
EchoSession(const Socket::Ptr &pSock) : Session(pSock){
|
|
|
DebugL;
|
|
|
}
|
|
|
virtual ~EchoSession(){
|
|
|
DebugL;
|
|
|
}
|
|
|
|
|
|
void onRecv(const Buffer::Ptr &buffer) override {
|
|
|
send(buffer);
|
|
|
}
|
|
|
void onError(const SockException &err) override{
|
|
|
WarnL << err.what();
|
|
|
}
|
|
|
|
|
|
void onManager() override {}
|
|
|
};
|
|
|
|
|
|
//命令(http) [AUTO-TRANSLATED:d96c7331]
|
|
|
// Command (http)
|
|
|
class CMD_pingpong: public CMD {
|
|
|
public:
|
|
|
CMD_pingpong(){
|
|
|
_parser.reset(new OptionParser(nullptr));
|
|
|
(*_parser) << Option('l', "listen", Option::ArgRequired, "10000", false, "服务器模式:监听端口", nullptr);
|
|
|
//测试客户端个数,默认10个 [AUTO-TRANSLATED:5a5a229a]
|
|
|
// Test client count, default 10
|
|
|
(*_parser) << Option('c', "count", Option::ArgRequired, to_string(10).data(), false, "客户端模式:测试客户端个数", nullptr);
|
|
|
//默认每次发送1MB的数据 [AUTO-TRANSLATED:22373e35]
|
|
|
// Default send 1MB data each time
|
|
|
(*_parser) << Option('b', "block", Option::ArgRequired, to_string(1024 * 1024).data(), false, "客户端模式:测试数据块大小", nullptr);
|
|
|
//默认1秒发送10次,总速度率为1MB/s * 10 * 10 = 100MB/s [AUTO-TRANSLATED:d3b7bb36]
|
|
|
// Default send 10 times per second, total speed rate is 1MB/s * 10 * 10 = 100MB/s
|
|
|
(*_parser) << Option('i', "interval", Option::ArgRequired, to_string(100).data(), false, "客户端模式:测试数据发送间隔,单位毫秒", nullptr);
|
|
|
//客户端启动间隔时间 [AUTO-TRANSLATED:b401adf1]
|
|
|
// Client startup interval time
|
|
|
(*_parser) << Option('d', "delay", Option::ArgRequired, "50", false, "服务器模式:客户端启动间隔时间", nullptr);
|
|
|
|
|
|
//指定服务器地址 [AUTO-TRANSLATED:867c9c2d]
|
|
|
// Specify server address
|
|
|
(*_parser) << Option('s', "server", Option::ArgRequired, "127.0.0.1:10000", false, "客户端模式:测试服务器地址", []
|
|
|
(const std::shared_ptr<ostream> &stream, const string &arg) {
|
|
|
if (arg.find(":") == string::npos) {
|
|
|
//中断后续选项的解析以及解析完毕回调等操作 [AUTO-TRANSLATED:15b7592f]
|
|
|
// Interrupt subsequent option parsing and parsing completion callback, etc.
|
|
|
throw std::runtime_error("\t地址必须指明端口号.");
|
|
|
}
|
|
|
//如果返回false则忽略后续选项的解析 [AUTO-TRANSLATED:01a3d6bc]
|
|
|
// If return false, ignore subsequent option parsing
|
|
|
return true;
|
|
|
});
|
|
|
}
|
|
|
|
|
|
~CMD_pingpong() {}
|
|
|
|
|
|
const char *description() const override {
|
|
|
return "tcp回显性能测试";
|
|
|
}
|
|
|
};
|
|
|
|
|
|
|
|
|
EventPoller::Ptr nextPoller(){
|
|
|
static vector<EventPoller::Ptr> s_poller_vec;
|
|
|
static int s_poller_index = 0;
|
|
|
if(s_poller_vec.empty()){
|
|
|
EventPollerPool::Instance().for_each([&](const TaskExecutor::Ptr &executor){
|
|
|
s_poller_vec.emplace_back(static_pointer_cast<EventPoller>(executor));
|
|
|
});
|
|
|
}
|
|
|
auto ret = s_poller_vec[s_poller_index++];
|
|
|
if(s_poller_index == s_poller_vec.size()){
|
|
|
s_poller_index = 0;
|
|
|
}
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
int main(int argc,char *argv[]){
|
|
|
CMD_pingpong cmd;
|
|
|
try{
|
|
|
cmd(argc,argv);
|
|
|
}catch (std::exception &ex){
|
|
|
cout << ex.what() << endl;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
//初始化环境 [AUTO-TRANSLATED:efbad911]
|
|
|
// Initialize environment
|
|
|
Logger::Instance().add(std::shared_ptr<ConsoleChannel>(new ConsoleChannel()));
|
|
|
Logger::Instance().setWriter(std::shared_ptr<LogWriter>(new AsyncLogWriter()));
|
|
|
|
|
|
{
|
|
|
int interval = cmd["interval"];
|
|
|
int block = cmd["block"];
|
|
|
auto ip = cmd.splitedVal("server")[0];
|
|
|
int port = cmd.splitedVal("server")[1];
|
|
|
int delay = cmd["delay"];
|
|
|
auto buffer = BufferRaw::create();
|
|
|
buffer->setCapacity(block);
|
|
|
buffer->setSize(block);
|
|
|
|
|
|
TcpServer::Ptr server(new TcpServer);
|
|
|
server->start<EchoSession>(cmd["listen"]);
|
|
|
for(auto i = 0; i < cmd["count"].as<int>() ; ++i){
|
|
|
auto poller = nextPoller();
|
|
|
auto socket = Socket::createSocket(poller, false);
|
|
|
|
|
|
socket->connect(ip,port,[socket,poller,interval,buffer](const SockException &err){
|
|
|
if(err){
|
|
|
WarnL << err.what();
|
|
|
return;
|
|
|
}
|
|
|
socket->setOnErr([](const SockException &err){
|
|
|
WarnL << err.what();
|
|
|
});
|
|
|
socket->setOnRead([interval,socket](const Buffer::Ptr &buffer, struct sockaddr *addr , int addr_len){
|
|
|
if(!interval){
|
|
|
socket->send(buffer);
|
|
|
}
|
|
|
});
|
|
|
|
|
|
if(interval){
|
|
|
poller->doDelayTask(interval,[socket,interval,buffer](){
|
|
|
socket->send(buffer);
|
|
|
return interval;
|
|
|
});
|
|
|
}else{
|
|
|
socket->send(buffer);
|
|
|
}
|
|
|
});
|
|
|
usleep(delay * 1000);
|
|
|
}
|
|
|
|
|
|
//设置退出信号处理函数 [AUTO-TRANSLATED:4f047770]
|
|
|
// Set exit signal handling function
|
|
|
static semaphore sem;
|
|
|
signal(SIGINT, [](int) { sem.post(); });// 设置退出信号
|
|
|
sem.wait();
|
|
|
}
|
|
|
return 0;
|
|
|
} |