acl/lib_fiber/samples/tcp_client/main.cpp

228 lines
4.1 KiB
C++

#include "stdafx.h"
#include <string.h>
static bool __read_echo = false;
static int __cocurrent = 10;
static void run_pool(const char* addr, int length, int count)
{
acl::string buf;
acl::tcp_pool pool(addr, 0);
char* s = (char*) malloc(length + 1);
memset(s, 'x', length);
s[length] = 0;
for (int i = 0; i < count; i++)
{
#if 1
if (!pool.send(s, length, __read_echo ? &buf : NULL))
{
printf("send error to %s\r\n", addr);
break;
}
buf.clear();
#else
acl::tcp_client* conn = (acl::tcp_client*) pool.peek();
if (conn == NULL)
{
printf("peek error from %s\r\n", addr);
break;
}
if (!conn->send(s, length, __read_echo ? &buf : NULL))
{
pool.put(conn, false);
printf("send error to %s\r\n", addr);
break;
}
pool.put(conn);
buf.clear();
#endif
}
}
static void run_ipc(const char* addr, acl::tcp_ipc& ipc, int length, int count)
{
acl::string buf;
char* s = (char*) malloc(length + 1);
memset(s, 'x', length);
s[length] = 0;
for (int i = 0; i < count; i++)
{
if (ipc.send(addr, s, (unsigned) length,
__read_echo ? &buf : NULL) == false)
{
printf("send error\r\n");
break;
}
if (i > 0 && i % 100000 == 0)
{
char info[128];
snprintf(info, sizeof(info), "thread=%lu, i=%d",
acl::thread::thread_self(), i);
acl::meter_time(__FILE__, __LINE__, info);
}
}
free(s);
}
class thread_client : public acl::thread
{
public:
thread_client(acl::tcp_ipc& ipc, const char* addr,
int count, int length, bool ipc_mode)
: ipc_(ipc)
, addr_(addr)
, count_(count)
, length_(length)
, ipc_mode_(ipc_mode)
{
}
~thread_client(void) {}
protected:
void* run(void)
{
if (ipc_mode_)
run_ipc(addr_, ipc_, length_, count_);
else
run_pool(addr_, length_, count_);
return NULL;
}
private:
acl::tcp_ipc& ipc_;
acl::string addr_;
int count_;
int length_;
bool ipc_mode_;
};
class fiber_client : public acl::fiber
{
public:
fiber_client(acl::tcp_ipc& ipc, const char* addr, int count,
int length, bool ipc_mode)
: ipc_(ipc)
, addr_(addr)
, count_(count)
, length_(length)
, ipc_mode_(ipc_mode)
{
}
protected:
void run(void)
{
if (ipc_mode_)
run_ipc(addr_, ipc_, length_, count_);
else
run_pool(addr_, length_, count_);
delete this;
if (--__cocurrent == 0)
acl::fiber::schedule_stop();
}
private:
acl::tcp_ipc& ipc_;
acl::string addr_;
int count_;
int length_;
bool ipc_mode_;
~fiber_client(void) {}
};
static void usage(const char* procname)
{
printf("usage: %s -s server\r\n"
" -n count\r\n"
" -c cocurrent[default: 4]\r\n"
" -l data_size\r\n"
" -f [if use fiber]\r\n"
" -i [if ipc_mode]\r\n"
" -r [if read echo]\r\n",
procname);
}
int main(int argc, char* argv[])
{
int ch, count = 10, cocurrent = 4, n = 10;
bool ipc_mode = false, fiber_mode = false;
acl::string addr("127.0.0.1:8887");
while ((ch = getopt(argc, argv, "hs:n:c:l:irf")) > 0)
{
switch (ch)
{
case 'h':
usage(argv[0]);
return 0;
case 's':
addr = optarg;
break;
case 'n':
count = atoi(optarg);
break;
case 'c':
cocurrent = atoi(optarg);
break;
case 'l':
n = atoi(optarg);
break;
case 'i':
ipc_mode = true;
break;
case 'r':
__read_echo = true;
break;
case 'f':
fiber_mode = true;
break;
default:
usage(argv[0]);
return 0;
}
}
acl::tcp_ipc ipc;
if (fiber_mode)
{
__cocurrent = cocurrent;
for (int k = 0 ; k < cocurrent; k++)
{
fiber_client* fb = new fiber_client(ipc, addr, count,
n, ipc_mode);
fb->start();
}
acl::fiber::schedule();
}
else
{
std::vector<acl::thread*> threads;
for (int k = 0; k < cocurrent; k++)
{
thread_client* thread =
new thread_client(ipc, addr, count, n, ipc_mode);
thread->set_detachable(false);
threads.push_back(thread);
thread->start();
}
for (std::vector<acl::thread*>::iterator it = threads.begin();
it != threads.end(); ++it)
{
(*it)->wait();
delete *it;
}
}
return 0;
}