#include "stdafx.h" #include 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 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::iterator it = threads.begin(); it != threads.end(); ++it) { (*it)->wait(); delete *it; } } return 0; }