You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
6.1 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* 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;
}