p2p即时聊天系统_第1页
p2p即时聊天系统_第2页
p2p即时聊天系统_第3页
p2p即时聊天系统_第4页
p2p即时聊天系统_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一、一、课程设计题目课程设计题目基于 P2P 的局域网即时通信系统二、二、实验环境及工具实验环境及工具1计算机:PC 机,PC 虚拟机,2操作系统:Windows2000,WindowsXP3程序设计语言: VC 6.0三、三、设计要求设计要求1实现一个图形用户界面局域网内的消息系统。2功能:建立一个局域网内的简单的 P2P 消息系统,程序既是服务器又是客户,服务器端口使用 3333。a)用户注册及对等方列表的获取:对等方 A 启动后,用户设置自己的信息(用户名,所在组);扫描网段中在线的对等方(3333 端口打开),向所有在线对等方的服务端口发送消息,接收方接收到消息后,把对等方 A 加入到

2、自己的用户列表中,并发应答消息;对等方 A 把回应消息的其它对等方加入用户列表。双方交换的消息格式自己根据需要定义,至少包括用户名、IP 地址。b)发送消息和文件:用户在列表中选择用户,与用户建立 TCP 连接,发送文件或消息。3用户界面:界面上包括对等方列表;消息显示列表;消息输入框;文件传输进程显示及操作按钮或菜单。四、四、设计内容与步骤设计内容与步骤1学习 Socket 和 TCP 的基本原理和通信机制;2功能设计和界面设计3服务器功能的设计和实现 4客户功能的设计和实现5 课程设计任务说明书五、五、方案设计方案设计1消息格式本系统采用的消息格式是,文件头+消息内容文件头为 1-9,消息

3、格式分配如下:1+本机名:本机名:登陆,发送给所有在线对等方的服务端口2+本机名:本机名:对登陆消息的回馈3+本机名:本机名:退出4+本机名:本机名:对话请求“51”或或”52”:对话请求的回应(是否同意)6+本机名本机名+”退出对话退出对话”:退出对话7+对话内容:对话内容:对话8+文件名长度文件名长度+文件名文件名+文件长度文件长度(转换成转换成 CString):请求传送“91”同意传输“92”拒绝“93”磁盘已满2该软件分别开了 3 个监听端口:3333、3334、3335。之所以分开 3 个端口是因为各种传送的不同,在设计实验的过程中我发现对于登陆消息,退出消息,应该用的 socke

4、t 是即用即断即用即断,即比如我收到登陆消息,并发送回馈消息后就断开连接,这样就不用一个用户同时连接很多用户,如果用完不断,就是全连接了。而文件传输应该跟对话传输分开,因此应该再开一个端口。3在线用户的扫描:本软件是通过扫描局域网内的在线用户(不一定打开软件),然后一一发送登陆信息,如果收到登陆信息就在列表上增加用户并发送回馈,如果收到回馈就在列表上增加用户,如果收到退出消息就删除用户。4文件传输原本打算使用多线程文件传输,及发送端开多个线程同时读一个文件并发送,接收端在磁盘开辟一个与接收文件大小一致的一个文件,然后接收端开多个线程接收并各自负责写进特定文件位置,不过由于 Socket匹配问题

5、,因此还是使用单线程传输比较简单一点。六、六、方案实现及主要程序方案实现及主要程序1工程中的类(1). 本软件中分别有三个 CAsyncSocket 的派生类,分别是CCtrlSocket,CTalkSocket,CFileSocketa)CCtrlSocket:用于接收及发送控制信息,包括文件头为1(登陆); 2(回馈);3(退出); 4(对话请求);5(对话请求的回应)的消息,对应监听端口是 CTRLPORT3333b)CTalkSocket:用于接收及发送对话信息,及部分文件控制信息。包括文件头为6(退出对话); 7(对话); 8(请求传送); 9(传送回应)的消息,对应监听端口是 TA

6、LKPORT3334c)CFileSocket:用于发送及接收文件,对应监听端口是 FILEPORT3335其它类如 CPathDialog,CFileDlg 与本设计的主要部分无紧要联系,故不一一说明了2类的具体实现(1). CCtrlSocket 类:类:主要部分有 FD_READ 及 FD_CONNECT 触发的事件,OnConnect 在建立连接后发送出相应的消息,而 OnReceive 在有消息到来的情况下处理消息void CCtrlSocket:OnReceive(int nErrorCode) / TODO: Add your specialized code here and/

7、or call the base classchar q50;char t;unsigned int j;CString tempaddr;CString Ctemp;UINT tempport;this-Receive(q,strlen(q)+1,0);t=q0;for(j=0;jm_pMainWnd;pDlg-UpdateData(true);switch(t)/对控制信息的判断case 1:/登陆pDlg-m_listonline.InsertItem(0,q); this-GetPeerName(tempaddr,tempport);pDlg-m_listonline.SetItemT

8、ext(0,1,tempaddr);Ctemp=2+pDlg-m_hostname;this-Send(Ctemp,strlen(Ctemp)+1,0);break;case 2:/回馈pDlg-m_listonline.InsertItem(0,q);this-GetPeerName(tempaddr,tempport);pDlg-m_listonline.SetItemText(0,1,tempaddr);break;case 3:/退出for(j=0;jm_listonline.GetItemCount();j+)if(pDlg-m_listonline.GetItemText(j,0)

9、=q)pDlg-m_listonline.DeleteItem(j);break;case 4:/请求对话Ctemp.Format(%s,q);Ctemp=是否接受+Ctemp+的对话请求?;if(AfxMessageBox(Ctemp, MB_YESNO|MB_ICONQUESTION) != IDYES)Ctemp=52;/拒绝this-Send(Ctemp,strlen(Ctemp)+1,0);break;else if(TalkSocket.m_hSocket!=INVALID_SOCKET)Ctemp=6+pDlg-m_hostname+退出对话;/断开原来对话TalkSocket.

10、Send(Ctemp,strlen(Ctemp)+1,0);Ctemp=51;/同意this-Send(Ctemp,strlen(Ctemp)+1,0);this-GetPeerName(tempaddr,tempport);pDlg-GetDlgItem(IDC_CUT_OFF)-EnableWindow(true);pDlg-GetDlgItem(IDC_SEND_MSS)-EnableWindow(true);pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(true);_tcpSocketClose(TalkSocket);_tcpSocketCo

11、nnect(TalkSocket,tempaddr,TALKPORT);pDlg-m_linkip=tempaddr;pDlg-m_linkname.Format(%s,q);break;case 5:/请求对话的回应if(q0=1) pDlg-m_editrec+=完成连接rn;pDlg-GetDlgItem(IDC_CUT_OFF)-EnableWindow(true);pDlg-GetDlgItem(IDC_SEND_MSS)-EnableWindow(true);pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(true);else if(q0=2

12、)AfxMessageBox(对方不想与你对话或者对方正忙!);else AfxMessageBox(Error!);break;default:break;pDlg-UpdateData(false);CAsyncSocket:OnReceive(nErrorCode);void CCtrlSocket:OnConnect(int nErrorCode) / TODO: Add your specialized code here and/or call the base classif(nErrorCode=0)this-AsyncSelect(FD_READ);CChatApp *pAp

13、p=(CChatApp *) AfxGetApp();CChatDlg *pDlg = (CChatDlg *) pApp-m_pMainWnd;pDlg-UpdateData(true);CString Ctemp;switch(SendMssKind)case 1:Ctemp=1+pDlg-m_hostname; this-Send(Ctemp,strlen(Ctemp)+1,0);break;case 3:Ctemp=3+pDlg-m_hostname; this-Send(Ctemp,strlen(Ctemp)+1,0);break;case 4:Ctemp=4+pDlg-m_host

14、name; this-Send(Ctemp,strlen(Ctemp)+1,0);break;default:break;CAsyncSocket:OnConnect(nErrorCode);(2). CTalkSocket 类:类:主要部分有 FD_READ 及 FD_CLOSE 触发的事件,OnClose 对方关掉软件后响应,而 OnReceive 在有消息到来的情况下处理消息void CTalkSocket:OnReceive(int nErrorCode) / TODO: Add your specialized code here and/or call the base class

15、char q150;unsigned int j;CString tempaddr;CString Ctemp;CString filename;CString filelen;long file_length;char RootPathName4; / root pathDWORD SectorsPerCluster; / sectors per clusterDWORD BytesPerSector; / bytes per sectorDWORD NumberOfFreeClusters; / free clustersDWORD TotalNumberOfClusters; / tot

16、al clusterslong DiskFree;this-Receive(q,strlen(q)+1,0);CChatApp *pApp=(CChatApp *) AfxGetApp();CChatDlg *pDlg = (CChatDlg *) pApp-m_pMainWnd;pDlg-UpdateData(true);char t=q0;for(j=0;jm_editrec=pDlg-m_editrec+Ctemp+rn;_tcpSocketClose(TalkSocket);pDlg-GetDlgItem(IDC_CUT_OFF)-EnableWindow(false);pDlg-Ge

17、tDlgItem(IDC_SEND_MSS)-EnableWindow(false);pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(false);break;case 7:/对话信息pDlg-m_editrec=pDlg-m_editrec+Ctemp+rn;break;case 8:/请求文件传输/q0=q0-48;filename=Ctemp.Mid(1,q0);file_length=atol(Ctemp.Right(Ctemp.GetLength()-q0-1);if(file_length1024)filelen.Format(%ld 字节,

18、file_length);else if(file_length1048576)filelen.Format(%.2fK,file_length/(float)1024);elseif(file_lengthSend(Ctemp,strlen(Ctemp)+1,0);else RootPathName0=pDlg-m_editdir0;RootPathName1=pDlg-m_editdir1;RootPathName2=pDlg-m_editdir2;RootPathName3=0;GetDiskFreeSpace(RootPathName,&SectorsPerCluster,&a

19、mp;BytesPerSector,&NumberOfFreeClusters,&TotalNumberOfClusters);DiskFree=(long)SectorsPerCluster*BytesPerSector*NumberOfFreeClusters;/大于一定数目会变成负数,不过只要小于 2G,即 1073741824*2就不会了if(DiskFreefile_length)pDlg-m_editfile=pDlg-m_editdir+filename;pDlg-m_filelen=filelen;Ctemp=91;/同意this-Send(Ctemp,strl

20、en(Ctemp)+1,0);CFile file;if(!file.Open(pDlg-m_editfile,CFile:modeCreate)AfxMessageBox(文件建立失败);file.Close();pDlg-file_length=file_length;pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(false);elseAfxMessageBox(磁盘空间不足,自动放弃接收文件!);Ctemp=93;/磁盘空间不足this-Send(Ctemp,strlen(Ctemp)+1,0);break;case 9:/请求文件传输的回应if

21、(q0=1) pDlg-m_editrec+=准备传输(请不要使用或移动传输的文件)rn;_tcpSocketClose(FileConn);_tcpSocketConnect(FileConn,pDlg-m_linkip,FILEPORT);pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(false);else if(q0=2)AfxMessageBox(对方不想接收你的文件!);elseif(q0=3)AfxMessageBox(对方磁盘已满,不能接收!);elseAfxMessageBox(Error!);break;case A:/结束文件传输b

22、reak;default:break;pDlg-UpdateData(false);CAsyncSocket:OnReceive(nErrorCode);void CTalkSocket:OnClose(int nErrorCode) / TODO: Add your specialized code here and/or call the base classCChatApp *pApp=(CChatApp *) AfxGetApp();CChatDlg *pDlg = (CChatDlg *) pApp-m_pMainWnd;pDlg-UpdateData(true);pDlg-m_ed

23、itrec+=对方下线rn;_tcpSocketClose(TalkSocket);pDlg-GetDlgItem(IDC_CUT_OFF)-EnableWindow(false);pDlg-GetDlgItem(IDC_SEND_MSS)-EnableWindow(false);pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(false);pDlg-UpdateData(false);CAsyncSocket:OnClose(nErrorCode);(3). CFileSocket 类:类:主要部分有 FD_READ 及 FD_WRITE 触发的事件,

24、OnSend 是在 Connect 建立连接后或缓存为空,可以准备发送,而OnReceive 在有消息到来的情况下处理消息,不过由于其它响应也比较重要,便也附上了void CFileSocket:OnAccept(int nErrorCode) / TODO: Add your specialized code here and/or call the base class_tcpSocketClose(FileSocket);if(!FileListen.Accept(FileSocket)AfxMessageBox(接收连接失败!);return;TotalRecv=0;TotalSend

25、=0;FileSocket.AsyncSelect(FD_READ);CAsyncSocket:OnAccept(nErrorCode);void CFileSocket:OnConnect(int nErrorCode) / TODO: Add your specialized code here and/or call the base classTotalRecv=0;TotalSend=0;FileConn.AsyncSelect(FD_WRITE);CAsyncSocket:OnConnect(nErrorCode);void CFileSocket:OnReceive(int nE

26、rrorCode) / TODO: Add your specialized code here and/or call the base classFileSocket.AsyncSelect(FD_CLOSE);CChatApp *pApp=(CChatApp *) AfxGetApp();CChatDlg *pDlg = (CChatDlg *) pApp-m_pMainWnd;pDlg-UpdateData(true);char recvbuf4096;CString Ctemp;CFile file;int dwRecv; int per;/文件进度if(!file.Open(pDl

27、g-m_editfile,CFile:modeWrite|CFile:shareDenyNone) elsedwRecv=0;memset(recvbuf,0,4096);dwRecv=this-Receive(recvbuf,4096,0);if(dwRecv!=0) file.SeekToEnd();file.Write(recvbuf,dwRecv);TotalRecv+=dwRecv;per=(int)(float)TotalRecv/(float)pDlg-file_length*100);pDlg-m_prog.SetPos(per);pDlg-m_per.Format(%d,pe

28、r);if(TotalRecv=pDlg-file_length)pDlg-m_editrec+=接收完毕rn; TotalRecv=0;pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(true);pDlg-UpdateData(false);file.Close();FileSocket.AsyncSelect(FD_READ|FD_CLOSE);CAsyncSocket:OnReceive(nErrorCode);void CFileSocket:OnSend(int nErrorCode) / TODO: Add your specialized

29、code here and/or call the base classthis-AsyncSelect(FD_CLOSE);CChatApp *pApp=(CChatApp *) AfxGetApp();CChatDlg *pDlg = (CChatDlg *) pApp-m_pMainWnd;pDlg-UpdateData(true);CString Ctemp; CFile file;char buf4096;UINT dwread;int per;/文件进度if(!file.Open(pDlg-m_editfile,CFile:modeRead)elsememset(buf,0,409

30、6);file.Seek(TotalSend,CFile:begin);dwread=file.Read(buf,4096);if(dwread!=0)TotalSend+=(long)dwread;FileConn.Send(buf,dwread,0);per=(int)(float)TotalSend/(float)pDlg-file_length*100);pDlg-m_prog.SetPos(per);pDlg-m_per.Format(%d,per);if(dwreadm_editrec+=发送完毕rn; file.Close();TotalSend=0;pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(true);elsefile.Close();this-AsyncSelect(FD_WRITE|FD_CLOSE);pDlg-UpdateData(false);CAsyncSocket:OnSend(nErrorCode);void CFileSocket:OnClose(int nErrorCode) / TODO: Add your specialized code here and/or call the base classthis-Close()

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论