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


#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")
#endif

USING_PTYPES

const 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 WIN32		
				CloseHandle(handle);
                #else
				pthread_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 queue
		message* 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 example
				quit = 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 pool
	for(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]);
			}

		}


	} //endwhile



	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值