压力测试工具程序 (使用ptypes库 里面的线程池来做)

来源:互联网 发布:戒指的牌子有哪些 知乎 编辑:程序博客网 时间:2024/05/16 04:52
#define WIN32 1#include <stdio.h>#include <pinet.h>#include <ptime.h>#include "packet.h"#include "logfile1.h"#include "config.h"#ifdef WIN32#pragma comment(lib, "ptypes.lib")#pragma comment(lib, "ws2_32.lib")#endifUSING_PTYPESconst int testport = 8088;const int maxtoken = 4096;const int maxthreads = 10000;const int MSG_MYJOB = MSG_USER + 1;bool g_bStop = false;struct CLIENTINFO{ipstream *pClient;CPacket  *pPacket;};class myjobthread: public thread{protected:int id;jobqueue* jq;virtual void execute();        void stopclear(){//停止时初始化一些变量running = 0;                #ifdef WIN32CloseHandle(handle);                #elsepthread_join(handle, nil);                #endif}public:myjobthread(int iid, jobqueue* ijq): thread(false), id(iid), jq(ijq)  {}~myjobthread()  { waitfor(); }};class myjob: public message{public:CLIENTINFO* m_pClientInfo;myjob(CLIENTINFO* pClientInfo): message(MSG_MYJOB), m_pClientInfo(pClientInfo)  {}~myjob()  { delete m_pClientInfo->pClient;delete m_pClientInfo->pPacket;delete m_pClientInfo; }};void myjobthread::execute(){bool quit = false;pout.putf("%t 进入线程ID: %d \n",now(),id);CLogFile::Instance()->LOG_WriteLine(LOG_INFO_HIT, "进入线程ID:%d", id);while (!quit ){// get the next message from the queuemessage* msg = jq->getmessage();CLogFile::Instance()->LOG_WriteLine(LOG_INFO_HIT, "获取到消息队列 线程ID:%d", id);try{switch (msg->id){case MSG_MYJOB:{BYTE szBuffer[MAXTOKEN];memset(szBuffer, 0x00, sizeof(szBuffer));CPacket* pPacket = ((myjob*)msg)->m_pClientInfo->pPacket;ipstream* pClient = ((myjob*)msg)->m_pClientInfo->pClient;//循环发送接收while(!g_bStop){int nLength = pPacket->Encode((BYTE*)szBuffer, MAXTOKEN); pout.putf("%t Sending a request to the server... threadID:%d \n",now(), id);//为了测试大连接,需要每个线程休眠一小段时间,等待其他线程进来。//Sleep(10000);//client.putline((char *)szBuffer);pClient->write(szBuffer, nLength);pClient->flush();CLogFile::Instance()->LOG_WriteLine(LOG_INFO_HIT, "发送数据成功,Socket:%d 长度:%d threadID:%d ",pClient->get_handle(), nLength, id);// receive the response//超时或者出错退出if (!pClient->waitfor(30000)){pout.putf("%t 网络接收超时或出错, Socket:%d \n",now(),pClient->get_handle());CLogFile::Instance()->LOG_WriteLine(LOG_INFO_WARN, "网络接收超时或出错, Socket:%d threadID:%d", pClient->get_handle(), id);break;}CLogFile::Instance()->LOG_WriteLine(LOG_INFO_HIT, "waitfor响应 ");memset(szBuffer, 0x00, sizeof(szBuffer));int nLen1=0,nLen2 = 0,nRemainLen=0;nLen1 = pClient->read(szBuffer,sizeof(UINT32)*3);CLogFile::Instance()->LOG_WriteLine(LOG_INFO_HIT, "接收数据成功1,Socket:%d 长度:%d threadID:%d ",pClient->get_handle(), nLen1, id);if (nLen1 <= 0){break;}nRemainLen = *(UINT32*)(szBuffer + sizeof(UINT32)*2) + sizeof(UINT32);nLen2 = pClient->read(szBuffer + nLen1, nRemainLen);CLogFile::Instance()->LOG_WriteLine(LOG_INFO_HIT, "接收数据成功2,Socket:%d 长度:%d threadID:%d ",pClient->get_handle(), nLen2, id);if (nLen2 <= 0){break;}UINT32 nCmdID = CPacket::GetCmdIDFromData(szBuffer);pout.putf("%t Received: CMDID:%x\n", now(), nCmdID);CLogFile::Instance()->LOG_WriteLine(LOG_INFO_HIT, "接收数据成功,Socket:%d 长度:%d threadID:%d ",pClient->get_handle(), nLength, id);//Sleep(1000000);}pClient->close();}break;case MSG_QUIT:// MSG_QUIT is not used in our examplequit = true;break;}}catch(exception*){// the message object must be freed!delete msg;throw;}delete msg;}pout.putf("%t 退出线程ID: %d \n",now(),id);CLogFile::Instance()->LOG_WriteLine(LOG_INFO_HIT, "退出线程ID:%d", id);//清除线程句柄stopclear();}int main(){CLogFile::Instance()->LOG_Start(".\\clipoollog\\");//获取配置文件CConfig cfConfig;char szServerIP[32];memset(szServerIP, 0x00, sizeof(szServerIP));int nPort = 0;int nThreadNum = 0;cfConfig.ReadConfigString("server", "ip", szServerIP, "127.0.0.1", 32, ".\\clipool.ini");nPort = cfConfig.ReadConfigInt("server", "port", testport, ".\\clipool.ini");nThreadNum = cfConfig.ReadConfigInt("client", "threadnum", maxthreads, ".\\clipool.ini");    //创建线程池jobqueue jobQueue;tobjlist<myjobthread> threads(true);myjobthread* pArrJobThread[maxthreads];// create the thread poolfor(int i = 0; i < nThreadNum; i++){pArrJobThread[i] = new myjobthread(i + 1, &jobQueue);pArrJobThread[i]->start();threads.add(pArrJobThread[i]);}Sleep(10);// create a client socket and send a greeting to the server// assuming that the server is on the same host (127.0.0.1)char chNum =0x00;while(1){pout.putf("=================================================================\n");pout.putf("=   输入1 发送开锁消息   输入2 发送报警消息                     =\n");pout.putf("=   输入3 发送文件升级   输入4 发送文件升级成功消息             =\n");pout.putf("=   输入5 发送广告升级   输入6 发送广告升级成功消息             =\n");pout.putf("=   输入7 设备文件抓拍   输入8 发送抓拍上传成功消息             =\n");pout.putf("=   输入a 发送时间校准   输入b 发送门禁开门过长消息             =\n");pout.putf("=   输入s 停止操作       输入q 或其他字母结束                   =\n");pout.putf("=================================================================\n");chNum = getchar();getchar();CPacket *pPacket;g_bStop = false;//循环启动for(int nNum = 0; nNum < nThreadNum; nNum++){if ('1' == chNum){pPacket = new CPacket_OpenUnitDoor;pPacket->SetTest(nNum);}else if ('2' == chNum){pPacket = new CPacket_Alarm;pPacket->SetTest(nNum);}else if ('3' == chNum){pPacket = new CPacket_UpdateFile;pPacket->SetTest(nNum);}else if ('4' == chNum){pPacket = new CPacket_UpdateFile;pPacket->SetTest2(nNum);}else if ('5' == chNum){pPacket = new CPacket_UpdateAdvertisement;pPacket->SetTest(nNum);}else if ('6' == chNum){pPacket = new CPacket_UpdateAdvertisement;pPacket->SetTest2(nNum);}else if ('7' == chNum){pPacket = new CPacket_UploadDevicePicture;pPacket->SetTest(nNum);}else if ('8' == chNum){pPacket = new CPacket_UploadDevicePicture;pPacket->SetTest2(nNum);}else if ('a' == chNum){pPacket = new CPacket_CalibrateTime;pPacket->SetTest();}else if ('b' == chNum){pPacket = new CPacket_LongOpenDoor;pPacket->SetTest(nNum);}else if ('s' == chNum){g_bStop = true;break;}else if ('q' == chNum){//退出return 0;}else{return 0;}CLIENTINFO *pClientInfo = new CLIENTINFO;pClientInfo->pPacket = pPacket;pClientInfo->pClient = new ipstream(szServerIP, nPort);try{//客户端进行连接pClientInfo->pClient->open();pout.putf("======================================================\n");pout.putf("%t: 第%d 客户端连接成功 Socket: %d \n", now(), nNum, pClientInfo->pClient->get_handle());jobQueue.post(new myjob(pClientInfo));}catch(estream* e){perr.putf("第%d Error: %s\n", nNum, pconst(e->get_message()));delete e;}//delete pPacket;} //end first for 跳出for循环//跳出for循环再处理线程池.if ('s' == chNum){//停止清除原来的发送数据//停止运行的线程类。for (int i = 0; i < nThreadNum; i++){//发送推出信号让线程池中运行的线程停止jobQueue.post(MSG_QUIT);threads.pop();}//启动线程池中的原线程//启动线程池for(int i = 0; i < nThreadNum; i++){if (NULL == pArrJobThread[i]){pArrJobThread[i] = new myjobthread(i, &jobQueue);}pArrJobThread[i]->start();threads.add(pArrJobThread[i]);}}} //endwhilereturn 0;}

原创粉丝点击