|
Posted on 2009-02-01 23:09 S.l.e!ep.¢% 閱讀(1547) 評(píng)論(0) 編輯 收藏 引用 所屬分類(lèi): test
修改了 INetwordable 接口, 將網(wǎng)絡(luò)程序中的“網(wǎng)絡(luò)通信”抽離出來(lái),方便寫(xiě)單元測(cè)試 #include?<windows.h>
#include?<iostream>
using?namespace?std;

//??網(wǎng)絡(luò)通信協(xié)議?
 /**///////////////////////////////////////////////////////////////////////////////?//? struct?cmd
  {
????int?nCmd;
};

#pragma?pack(1)
struct??tagClientLogin
  {
????cmd??header;
????char??username[?20?];
????char??userpwd[?20?];
}?;

struct??tagRepClientLogin
  {
????cmd??header;
????bool??bLoginSuccess;
};
#pragma?pack(1)

#define??NETWORK_CMD_LOGIN?1?
#define??NETWORK_CMD_REP_LOGIN?2?
 /**/////////////////////////////////////////////////////////////////////////////////?
//??接口定義?
 /**/////////////////////////////////////////////////////////////////////////////////? class??ClientObserver
  {
public?:
 ????ClientObserver()??? {}?
 ????~?ClientObserver()? {}?
????
????virtual?void?onRepLogin(?bool??bLoginSuccess)??=???0?;
}?;

 /**//*
class?INetWorkable
{
public?:
????INetWorkable()??{}?
????~INetWorkable()?{}?
????
????//??pvoid?:?欲發(fā)送的緩沖區(qū);?nSize?:?緩沖區(qū)的大小?
????virtual?bool??send(?const???void?*??pvoid,??int??nSize)?=?0?;
????
????//??由網(wǎng)絡(luò)層調(diào)用,pvoid:?接收到的數(shù)據(jù)的緩沖區(qū),?nSize?:?緩沖區(qū)的大小;??返回已經(jīng)處理的數(shù)據(jù)長(zhǎng)度?
????virtual?int?onreceive(?const???void?*??pvoid,??int??nSize)?=?0?;
};
*/

//?將原先的?INetWorkable?接口拆分成兩個(gè)類(lèi)
class?INetWorkSendable
  {
public?:
 ????INetWorkSendable()?? {}?
 ????~INetWorkSendable()? {}?
????
????//??pvoid?:?欲發(fā)送的緩沖區(qū);?nSize?:?緩沖區(qū)的大小?
????virtual?bool??send(?const???void?*??pvoid,??int??nSize)?=?0?;
};

class?INetWorkRecvable
  {
public?:
 ????INetWorkRecvable()?? {}?
 ????~INetWorkRecvable()? {}?
????
????//??由網(wǎng)絡(luò)層調(diào)用,pvoid:?接收到的數(shù)據(jù)的緩沖區(qū),?nSize?:?緩沖區(qū)的大小;??返回已經(jīng)處理的數(shù)據(jù)長(zhǎng)度?
????virtual?int?onreceive(?const???void?*??pvoid,??int??nSize)?=?0?;
};

class?ILogable
  {
public?:
 ????ILogable()??? {}?
 ????~?ILogable()??? {}?
????
????virtual?void?log(const?char*?plog)?=?0;
};
 /**/////////////////////////////////////////////////////////////////////////////////?
//??業(yè)務(wù)邏輯類(lèi)?
//??Client?現(xiàn)在只需要繼承?INetWorkRecvable?即可
 /**/////////////////////////////////////////////////////////////////////////////////? class??Client?:?public?INetWorkRecvable
  {
public?:
????Client()
 ???? {
????????m_pClientObserver?=?NULL;
????????m_plog?=?NULL;
????????m_pSendable?=?NULL;
????}

 ????virtual??~Client()? {}
????
 ????void??registerObserver(ClientObserver?*??p)??? {?m_pClientObserver??=??p;?}?
 ????void??removeObserver()??? {?m_pClientObserver??=??NULL;?}?
????
 ????void??setLoger(ILogable?*??p)??? {?m_plog??=??p;?}?
 ????void??removeLoger()??????????? {?m_plog??=??NULL;?}?
????
 ????void??setSendable(INetWorkSendable*?p)? {?m_pSendable?=?p;?}
 ????void??removeSendable(INetWorkSendable*?p)? {?m_pSendable?=?NULL;?}
?
????bool?SendLogin(const?char*?name,??const?char*?pwd)
 ???? {
????????tagClientLogin?login;
????????memset(?&?login,??0?,??sizeof?(login));
????????login.header.nCmd??=??NETWORK_CMD_LOGIN;
????????strncpy(login.username,?name,??sizeof?(login.username));????????
????????strncpy(login.userpwd,?pwd,??sizeof?(login.userpwd));

????????//?Sendable?改成了?"組合"?的方式后,每次調(diào)用?Send?都要判斷,?讓我很不爽
????????if(?m_pSendable?!=?NULL?)
 ???????? {
????????????return?m_pSendable->send(&login,??sizeof?(login));
????????}
????????else
 ???????? {
????????????return?false;
????????}
????}?
????
protected?:????
????virtual?int?onreceive(?const???void?*??pvoid,??int??nSize)
 ???? {
????????if??(?nSize??<???sizeof?(cmd)?)
????????????return???0?;
????????
????????cmd?*??pheader??=??(cmd?*?)pvoid;
????????
????????if??(?pheader?->?nCmd??==??NETWORK_CMD_REP_LOGIN?)
 ???????? {
????????????if??(?nSize??<???sizeof?(tagRepClientLogin)?)
????????????????return???0?;
????????????
????????????tagRepClientLogin?*??ptagRepClientLogin??=??(tagRepClientLogin?*?)pvoid;
????????????
????????????if??(?m_pClientObserver??!=??NULL?)
????????????????m_pClientObserver?->?onRepLogin(ptagRepClientLogin?->?bLoginSuccess);
????????????
????????????return???sizeof?(tagRepClientLogin);????
????????}?
????????
????????return???0?;
????}?
????
private?:
????ClientObserver?*??m_pClientObserver;
????ILogable?*????????m_plog;
????INetWorkSendable*?m_pSendable;
}?;?測(cè)試?yán)?br /> #include?"client.h"
#include?<string.h>

class?testClient?:?public?Client,?INetWorkSendable
  {
public:
 ????testClient()?? {?memset(m_buf,?0,?sizeof(m_buf));?}
 ????~testClient()? {}
????????
????int?NetWorkReceive(const?void*?pvoid,?int?nSize)
 ???? {
????????return?onreceive(pvoid,?nSize);
????}

????virtual?bool??send(const???void?*??pvoid,??int??nSize)
 ???? {
????????copyMemory(pvoid,?nSize);
????????return?true;
????}
????
????bool?cmpMemory(const?void*?pvoid,?int?nSize)
 ???? {
????????return?(?0?==?memcmp(m_buf,?pvoid,?nSize)?);
????}
????
????void?copyMemory(const?void*?pvoid,?int?nSize)
 ???? {
????????memcpy(m_buf,?pvoid,?nSize);
????}

private:
????char?m_buf[1024];
};

int?main()
  {
????testClient?test;
????test.setSendable((INetWorkSendable*)&test);

????test.SendLogin("test_username",?"test_pwd");
????
????tagClientLogin?clientlogin;
????memset(&clientlogin,?0,?sizeof(clientlogin));
????clientlogin.header.nCmd?=?NETWORK_CMD_LOGIN;
????strcpy(clientlogin.username,?"test_username");
????strcpy(clientlogin.userpwd,??"test_pwd");
????if(?!test.cmpMemory(&clientlogin,?sizeof(clientlogin))?)
????????cout?<<?"test?failed"?<<?endl;
????
 ????char?szBuf[1024]??=? {0};
????
????//?摸擬服務(wù)器發(fā)送的包長(zhǎng)度不足
????if(?0?!=?test.NetWorkReceive(szBuf,?sizeof(tagRepClientLogin)?-?10)?)
????????cout?<<?"test?failed"?<<?endl;
????
????//?摸擬服務(wù)器發(fā)送的包內(nèi)容非法
????if(?0?!=?test.NetWorkReceive(szBuf,?sizeof(tagRepClientLogin))?)
????????cout?<<?"test?failed"?<<?endl;
????
????tagRepClientLogin?repLogin;
????repLogin.header.nCmd?=?NETWORK_CMD_REP_LOGIN;
????memcpy(szBuf,?&repLogin,?sizeof(repLogin));
????
????//?摸擬服務(wù)器發(fā)送了正確的包
????if(?sizeof(tagRepClientLogin)?!=?test.NetWorkReceive(szBuf,?sizeof(tagRepClientLogin))?)
????????cout?<<?"test?failed"?<<?endl;
????
????return?0;
}
|