myicq情景源代码分析.docx

上传人:b****2 文档编号:17427823 上传时间:2023-07-25 格式:DOCX 页数:33 大小:29.63KB
下载 相关 举报
myicq情景源代码分析.docx_第1页
第1页 / 共33页
myicq情景源代码分析.docx_第2页
第2页 / 共33页
myicq情景源代码分析.docx_第3页
第3页 / 共33页
myicq情景源代码分析.docx_第4页
第4页 / 共33页
myicq情景源代码分析.docx_第5页
第5页 / 共33页
myicq情景源代码分析.docx_第6页
第6页 / 共33页
myicq情景源代码分析.docx_第7页
第7页 / 共33页
myicq情景源代码分析.docx_第8页
第8页 / 共33页
myicq情景源代码分析.docx_第9页
第9页 / 共33页
myicq情景源代码分析.docx_第10页
第10页 / 共33页
myicq情景源代码分析.docx_第11页
第11页 / 共33页
myicq情景源代码分析.docx_第12页
第12页 / 共33页
myicq情景源代码分析.docx_第13页
第13页 / 共33页
myicq情景源代码分析.docx_第14页
第14页 / 共33页
myicq情景源代码分析.docx_第15页
第15页 / 共33页
myicq情景源代码分析.docx_第16页
第16页 / 共33页
myicq情景源代码分析.docx_第17页
第17页 / 共33页
myicq情景源代码分析.docx_第18页
第18页 / 共33页
myicq情景源代码分析.docx_第19页
第19页 / 共33页
myicq情景源代码分析.docx_第20页
第20页 / 共33页
亲,该文档总共33页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

myicq情景源代码分析.docx

《myicq情景源代码分析.docx》由会员分享,可在线阅读,更多相关《myicq情景源代码分析.docx(33页珍藏版)》请在冰点文库上搜索。

myicq情景源代码分析.docx

myicq情景源代码分析

选择自CSDNclzzcl的Blog

1.第一个情景:

用户注册

这个情景主要用到的数据结构:

(1)IcqUser

让我们先来看IcqUser的代码,

classIcqUser:

publicIcqInfo{

public:

IcqUser();

voidload(DBInStream&in);

voidsave(DBOutStream&out);

stringpasswd;

uint8auth;

};

classIcqInfo:

publicContactInfo,publicDBSerialize{

public:

IcqInfo();

virtual~IcqInfo(){}

voidsave(DBOutStream&out);

voidload(DBInStream&in);

};

classContactInfo{

public:

QIDqid;

stringnick;

uint8face;

uint8gender;

uint8age;

stringcountry;

stringprovince;

stringcity;

stringemail;

stringaddress;

stringzipcode;

stringtel;

stringname;

uint8blood;

stringcollege;

stringprofession;

stringhomepage;

stringintro;

uint32status;

};

classDBSerialize{

public:

virtualvoidsave(DBOutStream&out)=0;

virtualvoidload(DBInStream&in)=0;

};

很明显可以看出它是用来存储人员基本信息的数据结构,它有两个方法save和load,我们来看看它们的代码,

可以想出它是用来将数据成员存入数据库和从数据库读出.DBSerialize是一个抽象类。

voidIcqUser:

:

load(DBInStream&in)

{

IcqInfo:

:

load(in);

in>>passwd>>auth;

}

voidIcqUser:

:

save(DBOutStream&out)

{

IcqInfo:

:

save(out);

out<

}

voidIcqInfo:

:

load(DBInStream&in)

{

in>>face>>nick>>age>>gender>>country>>province>>city;

in>>email>>address>>zipcode>>tel;

in>>name>>blood>>college>>profession>>homepage>>intro;

}

voidIcqInfo:

:

save(DBOutStream&out)

{

out<

out<

out<

}

/*

*Utilityclassthatreadsfromorwritestoadatablock

*/

classDBOutStream{

public:

DBOutStream(){

cursor=data;

}

char*getData(){

returndata;

}

intgetSize(){

return(cursor-data);

}

DBOutStream&operator<<(uint8b);

DBOutStream&operator<<(uint16w);

DBOutStream&operator<<(uint32dw);

DBOutStream&operator<<(constchar*str);

DBOutStream&operator<<(StrList&strList);

DBOutStream&operator<<(conststring&str){

returnoperator<<(str.c_str());

}

DBOutStream&operator<<(constQID&qid){

return(*this<

}

private:

chardata[MAX_BLOCK_SIZE];

char*cursor;

};

classDBInStream{

public:

DBInStream(void*d,intn){

cursor=data=(char*)d;

datalen=n;

}

DBInStream&operator>>(uint8&b);

DBInStream&operator>>(uint16&w);

DBInStream&operator>>(uint32&dw);

DBInStream&operator>>(string&str);

DBInStream&operator>>(StrList&strList);

DBInStream&operator>>(QID&qid){

return(*this>>qid.uin>>qid.domain);

}

private:

char*data;

char*cursor;

intdatalen;

};

(2)IcqOption

classIcqOption:

publicDBSerialize{

public:

IcqOption();

virtual~IcqOption();

voidload(DBInStream&in);

voidsave(DBOutStream&out);

voidplaySound(intsound,IcqContact*c=NULL);

bitsetflags;//Systemoptionflags

uint32hotKey;

stringsoundFiles[NR_SOUNDS];

stringhost;

uint16port;

stringautoReplyText;

stringquickReplyText;

uint32autoStatus;

uint32autoStatusTime;

stringskin;

//Proxystuff

uint8proxyType;

ProxyInfoproxy[NR_PROXY_TYPES];

private:

boolplaySound(constchar*file);

};

存储各种选项

在这个情景里,我们假定用户已经点击网络设置那一页的下一步按钮。

进入以下代码中:

BOOLCRegFinishDlg:

:

OnSetActive()

{

206CRegWizard*wiz=(CRegWizard*)GetParent();

207wiz->getData(&icqLink->myInfo,&icqLink->options);

首先206行取到上个窗口的指针,就是属性表的指针,进而调用它的函数getData。

进入代码:

CRegFinishDlg:

:

OnSetActive()-->CRegWizard:

:

getData()

54voidCRegWizard:

:

getData(IcqUser*info,IcqOption*options)

55{

56if(modeDlg.m_mode==0)

57info->qid=qid;

58else{

59info->qid.uin=modeDlg.m_uin;

60info->qid.domain=finishDlg.domain;

61}

62

63info->face=basicDlg.m_pic;

64info->age=basicDlg.m_age;

65info->nick=basicDlg.m_nick;

66info->gender=basicDlg.m_gender;

67info->country=basicDlg.m_country;

68info->province=basicDlg.m_province;

69info->city=basicDlg.m_city;

70

71info->email=commDlg.m_email;

72info->address=commDlg.m_address;

73info->zipcode=commDlg.m_zipcode;

74info->tel=commDlg.m_tel;

75

76info->name=miscDlg.m_name;

77info->blood=miscDlg.m_blood;

78info->college=miscDlg.m_college;

79info->profession=miscDlg.m_profession;

80info->homepage=miscDlg.m_homepage;

81info->intro=miscDlg.m_intro;

82

83info->passwd=(modeDlg.m_mode==0?

basicDlg.m_passwd:

modeDlg.m_passwd);

84

85if(options){

86options->host=networkDlg.m_host;

87options->port=networkDlg.m_port;

88options->flags.set(UF_USE_PROXY,networkDlg.m_useProxy);

89options->proxyType=networkDlg.m_proxyType;

90for(inti=0;i

91options->proxy[i]=networkDlg.proxyInfo[i];

92}

93}

此方法传入两个结构IcqUser和IcqOption以上有说明

第56行到第61行,主要给qid赋值,modeDlg.m_mode如选中新申请一个QQ号则为0,选中已有QQ号为1,本情景为0,也就是将info->qid=qid;qid是IcqWindow的一个公有变量QIDqid

classQID{

public:

QID(){

uin=0;

}

booloperator==(constQID&qid){

return(uin==qid.uin&&!

strcasecmp(domain.c_str(),qid.domain.c_str()));

}

boolisAdmin(){

return(uin==ADMIN_UIN&&domain.empty());

}

char*toString();

boolparse(constchar*qid);

uint32uin;

stringdomain;

};

剩下的代码就是根据这几个对话框所添入的东东给全局变量icqLink中的IcqUser和IcqOption的各成员变量赋值.

回到RegFinishDlg:

:

OnSetActive()中第208行开始,

208wiz->qid.uin=0;

209

210CStringstr;

211str.LoadString(IDS_PLEASE_WAIT);

212SetDlgItemText(IDC_STATUS,str);

213str.LoadString(IDS_REG_REGISTERING);

214SetDlgItemText(IDC_STATUS_DETAIL,str);

215wiz->SetWizardButtons(PSWIZB_DISABLEDFINISH);

216

217m_faceLabel.start();

218

219resolveHost();

220

221returnCPropertyPage:

:

OnSetActive();

}

这行将MyIcq号赋为0,211-218设置一些状态,219进入CRegFinishDlg:

:

resolveHost()

voidCRegFinishDlg:

:

resolveHost()

{

172  CRegWizard*wiz=(CRegWizard*)GetParent();

173  constchar*host=wiz->networkDlg.m_host;

174

175  if(wiz->networkDlg.m_useProxy&&!

wiz->networkDlg.m_proxyResolve)

176      getUdpSession()->connect(host,wiz->networkDlg.m_port);

177  else{

178      structin_addraddr;

179      addr.s_addr=inet_addr(host);//将x.x.x.x转换为无符号整数给addr.s_addr

180      if(addr.s_addr!

=INADDR_NONE)

181          onHostFound(addr);

182      else

183          ((CIcqDlg*)AfxGetMainWnd())->getHostByName(host);

   }

}

175行看出在网络设置对话框中有没有选使用代理服务器,本情景中没选到178行将用户选定的地址作为参数传给onHostFound(addr);进入onHostFound

voidCRegFinishDlg:

:

onHostFound(structin_addr&addr)

{

163  if(addr.s_addr!

=INADDR_NONE){

164      CRegWizard*wiz=(CRegWizard*)GetParent();

165      getUdpSession()->connect(inet_ntoa(addr),wiz->networkDlg.m_port);

166  }else

167      onTimeout();

}

在165行调用函数getUpdSession()->connect传入参数是用户输入的地址和端口。

inlineUdpSession*getUdpSession()

{

   returnicqLink->udpSession;

}

voidUdpSession:

:

connect(constchar*host,uint16port)

{

090  IcqOption&options=icqLink->options;

091

092  //Connectusingproxy

093  if(options.flags.test(UF_USE_PROXY)){

094      if(options.proxyType==PROXY_SOCKS)

095          socksProxy.start(options.proxy[PROXY_SOCKS],sock);

096      elseif(options.proxyType==PROXY_HTTP)

097              httpProxy.start(host,options.proxy[PROXY_HTTP]);  }

099  else{  //notuseproxy

100      sockaddr_inaddr;

101      socklen_tlen=sizeof(addr);

103      memset(&addr,0,sizeof(addr));

104      addr.sin_family=AF_INET;

105      addr.sin_port=htons(port);

106      addr.sin_addr.s_addr=inet_addr(host);

107      :

:

connect(sock,(sockaddr*)&addr,len);

109      getsockname(sock,(sockaddr*)&addr,&len);

110      realIP=ntohl(addr.sin_addr.s_addr);

112      icqLink->onConnect(true);

        }

}

首先判断有没有用proxy本情景中没有用所以到100行调用几个SOCKET函数连接传入的服务器及端口,将真实IP存放在realIP中,然后调用icqLink->onConnect(true);这个函数是一个虚函数,

CicqDlg类改写了它,所以程序进入CIcqDlg:

:

onConnect

voidCIcqDlg:

:

onConnect(boolsuccess)

{

292IcqWindow*win=findWindow(WIN_REG_WIZARD);

进入findWindow

IcqWindow*IcqLink:

:

findWindow(inttype,QID*qid,uint32seq)

{

   PtrList:

:

iteratorit;

   for(it=windowList.begin();it!

=windowList.end();++it){

       IcqWindow*win=(IcqWindow*)*it;

       if(win->type==type&&(!

qid||win->qid==*qid)

           &&(seq==0||win->seq==seq))

         returnwin;

       }

   returnNULL;

}

接上程序

293if(win){

294    ((CRegWizard*)win)->onConnect(success);

295    return;

296}

........}

本情景中WIN_REG_WIZARD存在所以进入((CRegWizard*)win)->onConnect(success);

voidonConnect(boolsuccess){

   finishDlg.onConnect(success);

}

voidCRegFinishDlg:

:

onConnect(boolsuccess)

{

148   if(success){

149       CRegWizard*wiz=(CRegWizard*)GetParent();

150       if(wiz->modeDlg.m_mode==0)

151           wiz->seq=getUdpSession()->regNewUIN(wiz->basicDlg.m_passwd);

152       else{

153         icqLink->myInfo.qid.uin=wiz->modeDlg.m_uin;

         wiz->seq=getUdpSession()->login(wiz->modeDlg.m_passwd,STATUS_OFFLINE);

155       }

156  }else

157       onTimeout();

}

modeDlg.m_mode如选中新申请一个QQ号则为0,选中已有QQ号为1,本情景为0所以到151行

uint16UdpSession:

:

regNewUIN(constchar*passwd)

{

 001  initSession();

 002  UdpOutPacket*out=createPacket(UDP_NEW_UIN);

 003  *out<

 004  returnsendPacket(out);

先看001regNewUIN主要功能是注册一个新ID,

voidUdpSession:

:

initSession()

{

161sid=(rand()&0x7fffffff)+1;   //将sid初值赋值为随机数

162sendSeq=(rand()&0x3fff);     

163retryKeepAlive=0;

164sessionCount=0;

165

166memset(window,0,sizeof(window));

167

168clearSendQueue();                       //清空发送队列

}

再看002

(1)UdpOutPacket*UdpSession:

:

createPacket(uint16cmd)

{

   UdpOutPacket*p=newUdpOutPacket;

   p->cmd=cmd;

   p->seq=++sendSeq;

   createPacket(*p,cmd,sendSeq);

   returnp;

}

(2)voidUdpSession:

:

createPacket(UdpOutPacket&out,uint16cmd,uint16seq)

{

   out<<(

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2