版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 10/10p2p即时聊天系统 一、课程设计题目 基于P2P的局域网即时通信系统 二、实验环境及工具 1计算机:PC机,PC虚拟机, 2操作系统:Windows2000,WindowsXP 3程序设计语言: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,消息格式分配如下: 1+本机名:登陆,发送给
3、所有在线对等方的服务端口 2+本机名:对登陆消息的回馈 3+本机名:退出 4+本机名:对话请求 “51”或”52”:对话请求的回应(是否同意) 6+本机名+”退出对话”:退出对话 7+对话内容:对话 8+文件名长度+文件名+文件长度(转换成CString):请求传送 “91”同意传输 “92”拒绝 “93”磁盘已满 2该软件分别开了3个监听端口:3333、3334、3335。之所以分开3个端口是因为各种传送的不同,在设计实验的过程中我发现对于登陆消息,退出消息,应该用的socket是即用即断,即比如我收到登陆消息,并发送回馈消息后就断开连接,这样就不用一个用户同时连接很多用户,如果用完不断,就
4、是全连接了。而文件传输应该跟对话传输分开,因此应该再开一个端口。 3在线用户的扫描: 本软件是通过扫描局域网内的在线用户(不一定打开软件),然后一一发送登陆信息,如果收到登陆信息就在列表上增加用户并发送回馈,如果收到回馈就在列表上增加用户,如果收到退出消息就删除用户。4文件传输 原本打算使用多线程文件传输,及发送端开多个线程同时读一个文件并发送,接收端在磁盘开辟一个与接收文件大小一致的一个文件,然后接收端开多个线程接收并各自负责写进特定文件位置,不过由于Socket匹配问题,因此还是使用单线程传输比较简单一点。 六、方案实现及主要程序 1工程中的类 (1).本软件中分别有三个CAsyncSoc
5、ket的派生类,分别是C CtrlSocket, CTalkSocket,CFileSocket a)CCtrlSocket:用于接收及发送控制信息,包括文件头为1(登陆);2 (回馈);3(退出);4(对话请求);5(对话请求的回应) 的消息,对应监听端口是CTRLPORT3333 b)CTalkSocket:用于接收及发送对话信息,及部分文件控制信息。包括 文件头为6(退出对话);7(对话);8(请求传送);9(传 送回应)的消息,对应监听端口是TALKPORT3334 c)CFileSocket:用于发送及接收文件,对应监听端口是FILEPORT 3335 其它类如CPathDialog
6、,CFileDlg与本设计的主要部分无紧要联系,故不一一说明了 2类的具体实现 (1).CCtrlSocket类:主要部分有FD_READ及FD_CONNECT触发的事件, OnConnect在建立连接后发送出相应的消息,而OnReceive在有消息 到来的情况下处理消息 void CCtrlSocket:OnReceive(int nErrorCode) / TODO: Add your specialized code here and/or call the base class char q50; char t; unsigned int j; CString tempaddr; CS
7、tring Ctemp; UINT tempport; this-Receive(q,strlen(q)+1,0); t=q0; for(j=0;jm_listonline.InsertItem(0,q); this-GetPeerName(tempaddr,tempport); pDlg-m_listonline.SetItemText(0,1,tempaddr); break; case 3:/退出 for(j=0;j m_listonline.GetItemCount();j+) if(pDlg-m_listonline.GetItemText(j,0)=q) pDlg-m_liston
8、line.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.Send(C
9、temp,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); _tcpSocket
10、Connect(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); e
11、lse if(q0=2) 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 class if(nErrorCode=0) this-AsyncSelect(F
12、D_READ); CChatApp *pApp=(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);
13、break; case 4: Ctemp=4+pDlg-m_hostname; 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 h
14、ere and/or call the base class char q150; unsigned int j; CString tempaddr; CString Ctemp; CString filename; CString filelen; long file_length; char RootPathName4; / root path DWORD SectorsPerCluster; / sectors per cluster DWORD BytesPerSector; / bytes per sector DWORD NumberOfFreeClusters; / free c
15、lusters DWORD TotalNumberOfClusters; / total clusters long 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;jGetDlgItem(IDC_SEND_MSS)-EnableWindow(false); pDlg-GetDlgItem(IDC_SEN
16、D_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_lengthSend(Ctemp,strlen(Ctemp)+1,0); else RootPathName0=pDlg-m_editdir0; RootPathName1=pDl
17、g-m_editdir1; RootPathName2=pDlg-m_editdir2; RootPathName3=0; GetDiskFreeSpace(RootPathName, DiskFree=(long)SectorsPerCluster*BytesPerSector*NumberOfFreeClust ers;/大于一定数目会变成负数,不过只要小于2G,即1073741824*2就不会了 if(DiskFreeSend(Ctemp,strlen(Ctemp)+1,0); break; case 9:/请求文件传输的回应 if(q0=1) pDlg-m_editrec+=准备传输(
18、请不要使用或移动传输的文件)rn; _tcpSocketClose(FileConn); _tcpSocketConnect(FileConn,pDlg-m_linkip,FILEPORT); pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(false); else if(q0=2) AfxMessageBox(对方不想接收你的文件!); else if(q0=3) AfxMessageBox(对方磁盘已满,不能接收!); else AfxMessageBox(Error!); break; case A:/结束文件传输 break; default:
19、break; pDlg-UpdateData(false); CAsyncSocket:OnReceive(nErrorCode); void CTalkSocket:OnClose(int nErrorCode) / TODO: Add your specialized code here and/or call the base class CChatApp *pApp=(CChatApp *) AfxGetApp(); CChatDlg *pDlg = (CChatDlg *) pApp-m_pMainWnd; pDlg-UpdateData(true); pDlg-m_editrec+
20、=对方下线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触发的事件, OnSend
21、是在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=0
22、; FileSocket.AsyncSelect(FD_READ); CAsyncSocket:OnAccept(nErrorCode); void CFileSocket:OnConnect(int nErrorCode) / TODO: Add your specialized code here and/or call the base class TotalRecv=0; TotalSend=0; FileConn.AsyncSelect(FD_WRITE); CAsyncSocket:OnConnect(nErrorCode); void CFileSocket:OnReceive(
23、int nErrorCode) / TODO: Add your specialized code here and/or call the base class FileSocket.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
24、(!file.Open(pDlg-m_editfile,CFile:modeWrite|CFile:shareDenyNone) else dwRecv=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);
25、 pDlg-m_per.Format(%d,per); 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 nErrorCod
26、e) / TODO: Add your specialized code here and/or call the base class this-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_edi
27、tfile,CFile:modeRead) else memset(buf,0,4096); 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_edit
28、rec+=发送完毕rn; file.Close(); TotalSend=0; pDlg-GetDlgItem(IDC_SEND_FILE)-EnableWindow(true); else file.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 class this-Close(); TotalRecv=0; TotalSend
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年度物流评估合同:物流企业评估服务协议3篇
- 二零二五年度代购服务合同范本(含客户信用评估)4篇
- 2025年度瓷砖品牌推广与广告投放合同4篇
- 二零二五年度楼顶广告牌广告内容更新与维护服务合同4篇
- 二零二五年度户外用瓷砖供货合同标准文本3篇
- 二零二五年度大米快递包邮配送与电商平台合作合同范本4篇
- 二零二五年度高端打印机定制化维修保养合同4篇
- 2025年度知识产权战略规划与实施合同4篇
- 二零二五年度智能温室彩钢棚建设与运营管理合同3篇
- 二零二五年度高端定制门窗设计与制造全流程服务合同3篇
- 2025年度公务车辆私人使用管理与责任协议书3篇
- 售后工程师述职报告
- 绿化养护难点要点分析及技术措施
- 2024年河北省高考历史试卷(含答案解析)
- 车位款抵扣工程款合同
- 小学六年级数学奥数题100题附答案(完整版)
- 高中综评项目活动设计范文
- 英汉互译单词练习打印纸
- 2023湖北武汉华中科技大学招聘实验技术人员24人笔试参考题库(共500题)答案详解版
- 一氯二氟甲烷安全技术说明书MSDS
- 物流签收回执单
评论
0/150
提交评论