p2p即时聊天系统
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、课程设计题目
基于P2P的局域网即时通信系统
二、实验环境及工具
1.计算机:PC机,PC虚拟机,
2.操作系统:Windows2000,WindowsXP
3.程序设计语言:VC 6.0
三、设计要求
1.实现一个图形用户界面局域网内的消息系统。
2.功能:建立一个局域网内的简单的P2P消息系统,程序既是服务器又是客户,服务器端口使用3333。
a)用户注册及对等方列表的获取:对等方A启动后,用户设置自己的
信息(用户名,所在组);扫描网段中在线的对等方(3333端口打
开),向所有在线对等方的服务端口发送消息,接收方接收到消息
后,把对等方A加入到自己的用户列表中,并发应答消息;对等方
A把回应消息的其它对等方加入用户列表。双方交换的消息格式自
己根据需要定义,至少包括用户名、IP地址。
b)发送消息和文件:用户在列表中选择用户,与用户建立TCP连接,
发送文件或消息。
3.用户界面:界面上包括对等方列表;消息显示列表;消息输入框;文件传输进程显示及操作按钮或菜单。
四、设计内容与步骤
1.学习Socket和TCP的基本原理和通信机制;
2.功能设计和界面设计
3.服务器功能的设计和实现
4.客户功能的设计和实现
5.课程设计任务说明书
五、方案设计
1.消息格式
本系统采用的消息格式是,文件头+消息内容
文件头为‘1’-‘9’,消息格式分配如下:
‘1’+本机名:登陆,发送给所有在线对等方的服务端口
‘2’+本机名:对登陆消息的回馈
‘3’+本机名:退出
‘4’+本机名:对话请求
“51”或”52”:对话请求的回应(是否同意)
‘6’+本机名+”退出对话”:退出对话
‘7’+对话内容:对话
‘8’+文件名长度+文件名+文件长度(转换成CString):请求传送
“91”同意传输
“92”拒绝
“93”磁盘已满
2.该软件分别开了3个监听端口:3333、3334、3335。之所以分开3个端口是因为各种传送的不同,在设计实验的过程中我发现对于登陆消息,退出消息,应该用的socket是即用即断,即比如我收到登陆消息,并发送回馈消息后就断开连接,这样就不用一个用户同时连接很多用户,如果用完不断,就是全连接了。而文件传输应该跟对话传输分开,因此应该再开一个端口。
3.在线用户的扫描:
本软件是通过扫描局域网内的在线用户(不一定打开软件),然后一一发送登陆信息,如果收到登陆信息就在列表上增加用户并发送回馈,如果收到回馈就在列表上增加用户,如果收到退出消息就删除用户。4.文件传输
原本打算使用多线程文件传输,及发送端开多个线程同时读一个文件并发送,接收端在磁盘开辟一个与接收文件大小一致的一个文件,然后接收端开多个线程接收并各自负责写进特定文件位置,不过由于Socket匹配问题,因此还是使用单线程传输比较简单一点。
六、方案实现及主要程序
1.工程中的类
(1).本软件中分别有三个CAsyncSocket的派生类,分别是C CtrlSocket,
CTalkSocket,CFileSocket
a)CCtrlSocket:用于接收及发送控制信息,包括文件头为‘1’(登陆);‘2’
(回馈);‘3’(退出);‘4’(对话请求);’5’(对话请求的回应)
的消息,对应监听端口是CTRLPORT——3333
b)CTalkSocket:用于接收及发送对话信息,及部分文件控制信息。包括
文件头为‘6’(退出对话);‘7’(对话);‘8’(请求传送);‘9’(传
送回应)的消息,对应监听端口是TALKPORT——3334
c)CFileSocket:用于发送及接收文件,对应监听端口是FILEPORT—
—3335
其它类如CPathDialog,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 q[50];
char t;
unsigned int j;
CString tempaddr;
CString Ctemp;
UINT tempport;
this->Receive(q,strlen(q)+1,0);
t=q[0];
for(j=0;j { q[j]=q[j+1]; } CChatApp *pApp=(CChatApp *) AfxGetApp(); CChatDlg *pDlg = (CChatDlg *) pApp->m_pMainWnd; pDlg->UpdateData(true); switch(t)//对控制信息的判断 { case '1'://登陆 pDlg->m_listonline.InsertItem(0,q); this->GetPeerName(tempaddr,tempport); pDlg->m_listonline.SetItemText(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;j if(pDlg->m_listonline.GetItemText(j,0)==q) { pDlg->m_listonline.DeleteItem(j); } } break;