网络数据通信编程论文.docx
- 文档编号:3724922
- 上传时间:2022-11-24
- 格式:DOCX
- 页数:25
- 大小:94.97KB
网络数据通信编程论文.docx
《网络数据通信编程论文.docx》由会员分享,可在线阅读,更多相关《网络数据通信编程论文.docx(25页珍藏版)》请在冰豆网上搜索。
网络数据通信编程论文
网络数据通信编程
一:
需求分析
1.背景
在线网络通信软件,如MSN,QQ等,不仅能够实现在线聊天,还能够实现网上传输各种文字、图片各音频、视频等文件,通信方式可以实现点对点、群发各广播,因此受到广大网络用户的喜爱。
本实例就是仿照聊天通信软件,实现其中的一部分功能,为网络用户提供在线短消息通信、文件传输服务。
2.功能需求
从实用角度出发,本实例主要考虑实现以下基本功能。
●对保持经常通信联系的人,列入远端通信目标的上线通知,显示各远端通信目标的在线状态。
●提供对无端通信目标的简短快捷的短消息通信,实际上就是简短的文字聊天。
●提供对远端通信目标的文件传输服务,只需知道对方的IP地址或计算机名即可进行通信。
3.界面要求
实例的界面设计主要考虑以下因素。
●显示远端通信目标的在线状态,当其上下线时能及时刷新状态。
●能方便地选取远端通信目标,进行短消息通信或者文件传输。
●能对短消息简单的编辑并显示其内容。
●能选取要传输的文件,在其传输过程中显示传输状态。
●为信使服务提供简单的短消息编辑功能和确定计算机名、IP地址的控件。
●应用程序界面简单实用,操作方便。
4.软硬件平台
本实例中用到Windows信使服务,这是Windows2000/windowsXP支持的功能,因此必须选择Windows2000/WindowsXP操作系统。
5.开发工具
开发工具选用VisualC++6.0。
二:
系统建模
1.用例分析
本实例用例如下图(1)所示。
图(1)
2.对象分析
根据对系统的用例分析,可以看出系统包括两在类对象:
远端通信目标、用户与远端通
信目标之间的交互信息。
对于保持经常联系的远端通信目标,可以抽象为CDestination类,将其常用的属性和方法封装到类中,以目标的网络ID作为唯一标识符,作为对象IP地址、主机名的别名,如下表所示。
而对于不经常联系的人,主要用IP地址和计算机名识别,由于使用Windows系统提供的信使服务进行通信,因此就不必创建专门的类。
远端通信目标的分析
对象
属性
方法
类
远端通信目标
目标的网络ID
目标IP地址
目标主机名
获取/设置目标ID
获取/设置目标主机名
获取/设置目标IP地址
CDestination
对于用户与远端通信目标之间的交互信息,可以归纳为上下线通知、短消息、文件等3类(如下表所示),其属性都很简单,获取要传送的文件可以由MFC的CFileDialog类实现。
对用户与远端通信目标之间交互信息的分析
对象
属性
方法
类
上下线通知
发送方ID
发送方主机名
消息类型(上线/下线)
无
MSG_NOTIFY
短消息
发送方ID
短消息内容
无
CMessage
文件
文件路径、文件名
获取文件路径、文件名
---
3.方法分析
可以将功能需求分为以下几部分。
(1) 在线状态管理
在线状态管理的内容包括:
上线时发送上线消息,在线时监听远端通信目标的状态,下线时则发送下线消息。
其UML活动图如下图
(2)所示。
其中的初始化包括创建界面窗口、加载WinSockCOM、加载系统配置文件、加载用户自身配置文件,系统的配置保存在bin/conf/config.xml文件中,用户自身配置文件保存在bin/conf/Profile.xml文件中。
(2)与远端通信目标的短消息通信
短消息通信是在在线状态下进行的,与监听远端通信目标状态、文件传输、信使服务
是并行的。
发送短消息需要指定接收方的远端通信目标。
短消息通信拥有自己的窗口,以便显示短消息内容和编辑发送的短消息。
其UML活动图如下图(3)所示。
图(2) 图(3)
(3)与远端通信目标的文件传输服务
文件传输也在在线状态下进行,也需要指定接收方的远端通信目标,通过CFileDialog查找要传递的文件,然后确认发送,就被发送到接收方的”..\File\”目录下。
其UML活动图如下图(4)所示。
(4)信使服务
信使服务用于与不经常联系的人进行通信服务,无需维护远端通信目标列表,只需输入对方的IP地址或主机名(局域网),就能发送简短消息,其UML活动图如下图(5)所示。
图(4) 图(5)
三:
界面设计
按照界面要求提出的需求,初步构想以下主要界面。
1.主界面
主界面分为与远端通信目标通信和信使服务两种状态,不使用时界面收缩到最小,不影响用户其他工作。
用列表来显示远端通信目标在线状态,目标上线则显示其网络名称,下线时则从列表中删除该目标,如下图(6)所示。
由于远端通信目标的短消息通信和发送文件都需要选择目标名,因此双击目标列表项即可打开一个新窗口(如图(7)所示),由于短消息通信及文件传输服务。
2.短消息及文件传输窗口
在此窗口中设置控件编辑消息、显示短消息内容,确认发送。
设置控件选取要传输的文件路径及文件名,可以直接使用CFileDialog。
此窗口仿照QQ及MSN的聊天窗口布置,如图(7)所示。
本例中限定短消息长少于128字(256Byte),因此可以用简短的Edit控件就可以了。
3.信使服务窗口
设置控件编辑短消息、输入计算机名或IP地址。
应考虑IP地址的特殊性(IP地址是点分16位数),此窗口布置如图(8)所示。
图(7)
图(6)
图(8)
四:
部分源代码
1.CMyessengerDlg类
voidCMyMessengerDlg:
:
ProcessOnlineMsg(CDestination*obj)
{
m_cs.Lock();
POSITIONpos=m_DestinationQueue.GetHeadPosition();
boolbExist=false;
for(;pos!
=NULL;m_DestinationQueue.GetNext(pos))
{
if(*m_DestinationQueue.GetAt(pos)==*obj)
{
bExist=true;
break;
}
}
if(bExist)
{
deleteobj;
}
else
{
m_DestinationQueue.AddTail(obj);
intnIndex=m_list.AddString(obj->GetName());//加到List中
if(LB_ERRSPACE==nIndex||LB_ERR==nIndex)
{
AfxMessageBox("加到列表时出错!
");
TRACE("加到列表时出错误!
\n");
ASSERT(FALSE);
}
else
{
m_list.SetItemDataPtr(nIndex,m_DestinationQueue.GetTailPosition());
}
}
m_cs.Unlock();
}
voidCMyMessengerDlg:
:
ProcessOfflineMsg(CDestination*obj)
{
m_cs.Lock();
POSITIONpos=m_DestinationQueue.GetHeadPosition();
boolbExist=false;
for(;pos!
=NULL;m_DestinationQueue.GetNext(pos))
{
if(*m_DestinationQueue.GetAt(pos)==*obj)
{
bExist=true;
break;
}
}
deleteobj;//删除对象
if(bExist)
{
CDestination*pDeleted=m_DestinationQueue.GetAt(pos);
m_DestinationQueue.RemoveAt(pos);//删除结点
if(!
pDeleted->Get_pDlg())//删除短消息与文件传输窗口
{
pDeleted->Get_pDlg()->SetPeer((POSITION)NULL);
pDeleted->Get_pDlg()->OnDestOffline(0,0);
}
//删除远端目标LIST上的条目,通过pos来找到.
for(inti=0;i { if(m_list.GetItemDataPtr(i)==pos) { m_list.DeleteString(i); break; } } //删除结点上的对象 deletepDeleted; } m_cs.Unlock(); } voidCMyMessengerDlg: : OpenChatDlg(POSITIONpos) { m_cs.Lock();//锁定目标链表中的结点,以免被释放。 //取得指定的目标结点 CDestination*pObj=m_DestinationQueue.GetAt(pos); CDlgChat*pDlg=pObj->Get_pDlg(); if(! pDlg) { //构造此目标的短消息与文件传输窗口 CStringstrRemoteIPAddress=pObj->GetIPAddress(); CStringstrRemoteNickName=pObj->GetName(); DWORDdwRemoteID=pObj->GetID(); pDlg=CDlgChat: : CreateRelatedWnd(pos,dwRemoteID,strRemoteNickName,strRemoteIPAddress); //将此结点与窗口绑定 m_DestinationQueue.GetAt(pos)->Set_pDlg(pDlg); } pDlg->ShowWindow(SW_RESTORE);//显示窗口 pDlg->SetForegroundWindow(); m_cs.Unlock(); } voidCMyMessengerDlg: : OnTimer(UINTnIDEvent) { SendOnlineMsg(); CDialog: : OnTimer(nIDEvent); } shortCMyMessengerDlg: : m_TransPort; voidCMyMessengerDlg: : SendDestinationMsg(MSG_NOTIFYdgm) { TRACE("BroadcastProfile开始...\n"); //使用UDP的socket,使用广播方式,MFC自动选择端口。 CWorkSocketwrkSocket; BOOLbErr=wrkSocket.Create(0,SOCK_DGRAM); if(! bErr) { TRACE("wrkSocket.Createerror(0x%x)\n",GetLastError()); ASSERT(FALSE); } BOOLval=TRUE; bErr=wrkSocket.SetSockOpt(SO_BROADCAST,&val,sizeof(BOOL)); if(! bErr) { TRACE("SetSockOpterror(0x%x)\n",GetLastError()); ASSERT(FALSE); } //将profile广播到其他机器的m_TransPort intnErr=wrkSocket.SendTo(&dgm,sizeof(dgm), CMyMessengerDlg: : m_TransPort,NULL); if(SOCKET_ERROR==nErr) { nErr=GetLastError(); TRACE("SendToerror(0x%x)\n",nErr); } else { //SendOK! ! TRACE("Broadcastprofileok! ! \n"); } wrkSocket.Close(); wrkSocket.ShutDown(); } voidCMyMessengerDlg: : OnDblclkList() { //与指定目标收发短消息 intnIndex=m_list.GetCurSel(); if(LB_ERR==nIndex) { AfxMessageBox("必须指定通信对象! "); } else { OpenChatDlg((POSITION)m_list.GetItemDataPtr(nIndex)); } } voidCMyMessengerDlg: : CloseChatDlg(POSITIONpos) { m_cs.Lock(); if(NULL! =pos) m_DestinationQueue.GetAt(pos)->Set_pDlg(NULL); m_cs.Unlock(); } LRESULTCMyMessengerDlg: : OnChatMsg(WPARAMwParam,LPARAMlParam) { CMessage*pDGram=(CMessage*)lParam; if(pDGram) { CDestination*pObj=SearchDestination(pDGram->m_dwNetMsgID); if(pObj) { //此目标结点是否有短消息与文件传输窗口。 if(pObj->Get_pDlg()) { //交给短消息与文件传输窗口处理 pObj->Get_pDlg()->OnRecv(pDGram->m_strMsg); } else { TRACE("信息来自%u,: %s\n",pDGram->m_dwNetMsgID,pDGram->m_strMsg); } } } deletepDGram; return0; } constCString&CMyMessengerDlg: : GetSelfName()const { returnm_strSelfName; } constDWORD&CMyMessengerDlg: : GetSelfID()const { returnm_dwSelfID; } 2.在线短消息服务 voidCDlgChat: : SendMsg() { TRACE("SendMsg()开始...\n"); //使用一个UDP的socket CWorkSocketworkSocket; BOOLbRet=workSocket.Create(0,SOCK_DGRAM); charbuf[1024]={0}; //SetchatMsgheader #pragmamessage("-Author-Entityproblemsolved! ") sprintf(buf," " " "" m_dwSelfID ""); try { IXMLDOMDocumentPtrxmlDoc(__uuidof(DOMDocument)); xmlDoc->async=false; xmlDoc->loadXML(_bstr_t(buf)); xmlDoc->selectSingleNode("ChatDiagram/Msg")->text=(constchar*)m_strMsg; strncpy(buf,xmlDoc->xml,sizeof(buf)); } catch(_com_error&e) { CStringsError="com_error: "; sError+=(constchar*)e.Description(); AfxMessageBox(sError); } //向对方m_strPeerIP的shortChatPort上发送短消息XML intnErr=workSocket.SendTo(buf,strlen(buf)+1 CDlgChat: : shortChatPort,m_strPeerIP); boolbSendOK=(SOCKET_ERROR! =nErr); if(bSendOK) { nErr=GetLastError(); TRACE("Sendmessageerror(0x%x)\n",nErr); } else { TRACE("Sendmessageok! ! \n"); } PostMessage(WM_CHAT_MSG,1,0); workSocket.Close(); } voidCDlgChat: : SaveMsg() { TRACE("%s\n",m_strSelfName); SaveMsg(m_strSelfName,m_strMsg); } //#pragmamessage("--OnRecv在收到对方短信息时,如果窗口没有打开,那么信息就不能被显示,这个要修改。 ") voidCDlgChat: : OnRecv(CStringstrMsg) { SaveMsg(m_strPeerName,strMsg); intnLen=m_MsgNote.GetWindowTextLength();//显示到短消息显示Edit末尾一行 m_MsgNote.SetSel(nLen,nLen); CStringstrTemp=m_strPeerName+": "+strMsg+"\r\n"; m_MsgNote.ReplaceSel(strTemp); } voidCDlgChat: : OnSend() { UpdateData(TRUE); //禁止发送按钮和输入编辑框 m_Send.EnableWindow(FALSE); m_Msg.EnableWindow(FALSE); SendMsg();//发送信息 SaveMsg();//保存信息 intnLen=m_MsgNote.GetWindowTextLength();//显示信息到最后一行。 m_MsgNote.SetSel(nLen,nLen); CStringstrTemp=m_strSelfName+": "+m_strMsg+"\r\n"; m_MsgNote.ReplaceSel(strTemp); //清空输入框 m_strMsg=""; UpdateData(FALSE); } voidCDlgChat: : SaveMsg(CStringspeaker,CStringstrMsg) { externCMyMessengerApptheApp; CStringstrFileName; strFileName.Format((theApp.GetWorkDIR()+"chat\\%u"),m_dwPeerID); CStringstrPut=speaker+": "; strPut+=strMsg+"\n"; try { CStdioFilefile(strFileName,CFile: : modeCreate|CFile: : modeNoTruncate |CFile: : modeWrite|CFile: : shareDenyWrite|CFile: : typeText); file.SeekToEnd(); file.WriteString(strPut); } catch(CFileException&e) { e.ReportError(); } } shortCDlgChat: : shortChatPort=0; voidCDlgChat: : PostNcDestroy() { TRACE("删除短消息对话框。 \n",m_strPeerName); CMyMessengerDlg*pMainWnd=static_cast pMainWnd->CloseChatDlg(m_posPeer); ShutDownRelation(); CDialog: : PostNcDestroy(); deletethis; } voidCDlgChat: : OnClose() { //CMyMessengerDlg*pMainWnd=static_cast //pMainWnd->CloseChatDlg(m_posPeer); //ShutDownRelation(); DestroyWindow(); } 3.文件传输服务 voidCDlgChat: : OnSendFiles() { CFileDialogdlg(TRUE); if(IDOK==dlg.DoModal()) { AfxMessageBox(dlg.m_ofn.lpstrFile); SendFile(dlg.m_ofn.lpstrFile); } } voidCDlgChat: : SendFile(CStringstrFileName) {
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 数据通信 编程 论文
![提示](https://static.bdocx.com/images/bang_tan.gif)