网络编程技术课程设计报告.docx

上传人:b****6 文档编号:15848958 上传时间:2023-07-08 格式:DOCX 页数:31 大小:276.54KB
下载 相关 举报
网络编程技术课程设计报告.docx_第1页
第1页 / 共31页
网络编程技术课程设计报告.docx_第2页
第2页 / 共31页
网络编程技术课程设计报告.docx_第3页
第3页 / 共31页
网络编程技术课程设计报告.docx_第4页
第4页 / 共31页
网络编程技术课程设计报告.docx_第5页
第5页 / 共31页
网络编程技术课程设计报告.docx_第6页
第6页 / 共31页
网络编程技术课程设计报告.docx_第7页
第7页 / 共31页
网络编程技术课程设计报告.docx_第8页
第8页 / 共31页
网络编程技术课程设计报告.docx_第9页
第9页 / 共31页
网络编程技术课程设计报告.docx_第10页
第10页 / 共31页
网络编程技术课程设计报告.docx_第11页
第11页 / 共31页
网络编程技术课程设计报告.docx_第12页
第12页 / 共31页
网络编程技术课程设计报告.docx_第13页
第13页 / 共31页
网络编程技术课程设计报告.docx_第14页
第14页 / 共31页
网络编程技术课程设计报告.docx_第15页
第15页 / 共31页
网络编程技术课程设计报告.docx_第16页
第16页 / 共31页
网络编程技术课程设计报告.docx_第17页
第17页 / 共31页
网络编程技术课程设计报告.docx_第18页
第18页 / 共31页
网络编程技术课程设计报告.docx_第19页
第19页 / 共31页
网络编程技术课程设计报告.docx_第20页
第20页 / 共31页
亲,该文档总共31页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

网络编程技术课程设计报告.docx

《网络编程技术课程设计报告.docx》由会员分享,可在线阅读,更多相关《网络编程技术课程设计报告.docx(31页珍藏版)》请在冰点文库上搜索。

网络编程技术课程设计报告.docx

网络编程技术课程设计报告

 

课程设计(论文)

 

题目名称聊天软件的开发

课程名称网络编程技术课程设计

学生姓名

学号

系、专业

指导教师

 

2016年5月22日

 

摘要

聊天程序一般采用互连网中继聊天协议,即双方即时通信的过程中必须通过第三方中转,第三方为服务器,聊天程序一般采用UDP协议,在基于UDP协议的基础上,聊天过程中消息的发送必须遵守某一种约定,这种约定规定了“进入聊室”、“发送聊天信息”和“离开聊天室”数据传输格式,中转者(服务器)通过接收客户端不同的数据格式来进行判断消息发送者欲进行的操作,然后对消息进行处理后再进行转发。

本次课程设计主要是利用MFC所提供的各种控件,基于C/S模式,设计的一个简单聊天软件。

关键词:

VisualC++6.0,客户端-服务器(C/S)结构,简单聊天软件

 

1前言

本次课程设计主要是利用MFC所提供的各种控件,基于C/S模式,设计的一个简单聊天软件。

聊天软件由客户端和服务器两部分构成,服务器充当“中转者”的职能,客户端将自己的消息首先发给服务器,服务器再根据需要将它们转发给其他客户端。

聊天程序一般采用互连网中继聊天协议,即双方即时通信的过程中必须通过第三方中转,第三方为服务器,聊天程序一般采用UDP协议,在基于UDP协议的基础上,聊天过程中消息的发送必须遵守某一种约定,这种约定规定了”进入聊天室”,”发送聊天信息”和”离开聊天室”数据传输格式,中转者(服务器)通过接收客户端不同的数据格式来进行判断消息发送者欲进行的操作,然后对消息进行处理后再进行转发,服务器根据接收到的不同消息格式做出不同的处理。

2需求分析

2.1任务和要求

本次课程设计内容任务是简单群聊软件的设计与实现。

三人以上为一组,其中一个同学为群聊软件的服务器端,另外同学为群聊软件客户端,服务器开启后公布其IP地址和端口号,客户端用服务器的IP地址和端口号进行登录,观察服务器与客户端的显示的结果,然后由客户端发送群聊消息,观察服务器与各客户端的显示结果。

具体要求如下:

1.采用客户端——服务器(C/S)结构,聊天室软件由客户端和服务器两部分构成,即创建两个工程,服务器(SelfRoom)和客户端(SelfChat)。

2.服务器的对话框界面应具有聊天室IP、端口、开启、关闭、聊天室动态、在线用户等基本内容,而客户端的对话框界面应具有昵称、聊天室IP、端口、登录、离开、聊天记录、在线好友等基本内容,添加相应的成员函数,使程序能正常运行。

3.聊天程序采用UDP协议,基于UDP协议的聊天过程中遵守一种约定,这种约定规定了“进入或离开聊天室”和“发送聊天信息”数据传输格式,服务器作为“中转者”通过接收客户端不同的数据格式来进行判断消息发送者的欲进行的操作,然后对消息进行处理后再进行转发。

2.2应实现的功能

此次课程设计内容是群聊软件的设计与实现,采用MFC类编程。

下面介绍一下服务器和客户端所实现的功能。

服务器的界面中有管理员、聊天室IP、端口、聊天室动态和在线用户列表,还有“开启”、“关闭”、“退出”按钮。

运行服务器时,先进行管理员、聊天室IP、端口的配置,点击“开启”按钮后,聊天室动态的文本框里会显现“聊天室开启成功”等消息以及当时得时间,便可等待成员的加入;当有成员加入时,也会有相应的提示信息,用户列表也会及时更新;当客户端发来消息,服务器会将此消息转发给每一个成员;当列表中的所有成员都离开时,服务器可点击“关闭”,即关闭聊天室。

客户端的界面有您的昵称、聊天室IP、端口、聊天文本框、在线好友列表,还有“进入”、“离开”、“发送”按钮。

运行客户端时,先进行昵称、聊天室IP、端口的配置,点击“进入”按钮,与服务器进行了连接;连接成功后,可发送聊天消息点击“发送”就能将消息发送到服务器,让服务器进行处理,发送的信息会显示在聊天框里,每条消息前面还附有发送消息时的时间,在线好友列表中会显示已进入聊天室的成员,可以与他们进行群聊,由于这只是简单的群聊软件,所以只能发送文字信息,不具备发送表情、文件等高级功能;当有成员加入或离开聊天室时,聊天框内会有提示信息,在线好友列表也会即时更新;当客户端想离开时,可以点击“离开”按钮,即可退出聊天室。

2.3界面及控件变量

(一)服务器

运行界面,如图2.1。

图2.1服务器界面图

(二)客户端

运行界面,如图2.2。

图2.2客户端运行界面图

3分析和设计

3.1系统分析及设计思路

本次聊天软件采用MFC编程,需要创建2个工程,分别是客户端工程SelfChat和服务器工程SelfRoom,由于本次软件需用到套接字类,所以在创建工程的时候需要选择“WindowsSockets”复选框,并都基于基本对话框。

在制作服务器的时候需要添加两个基于CSocket的套接字:

CClientSocket(用来监听)和CServerSocket(为每个加入聊天室的客户端生成一个相应的对象与之通信),另外添加一个C++结构体tagHeader(用于客户端和服务器之间辨识消息类型的)。

在制作客户端时添加一个基于CSocket的套接字类CClientSocket(用于连接服务器通信),和服务器一样要添加一个C++结构体tagHeader。

整个流程中的事件时序如下:

1.服务器配置管理员、聊天室IP以及端口后,单击“开启”按钮,此时服务器主动调用Listen()开始监听。

2.客户端配置昵称、聊天室IP以及端口后,单击“进入”按钮,此时客户端向服务器发起连接Connect()请求,若请求被接收,则紧接着发送会话消息。

3.服务器的CServerSocket类接收请求并触发OnAccept()事件,该事件过程创建对应请求方客户端的CClientSocket类对象并添加到Socket队列。

4.更多成员客户端加入时,服务器重复步骤3。

5.某个成员(客户端)要发送聊天消息时,在发送信息文本框中编辑文字,单击“发送”按钮向服务器发出消息。

6.某个成员(客户端)发来的消息到达服务器,触发服务器Socket队列中对应该客户端CClientSocket类对象的OnReceive()事件,对发来的消息进行处理。

7.服务器上对应该客户端的CClientSocket类对象,根据消息头tagHeader结构中的type字段辨别消息类型:

若type=LOGIN_IO,则表示有新成员加入,用广播方式通知所有其他成员客户端,并调用服务器UpdateUser()更新服务器用户列表;若type=SEND_MESSAGE,则表示这只是普通的成员的发言信息,直接广播转发该消息就可以了。

8.服务器发出的消息到达客户端,触发客户端本地OnReceive()事件,客户端本地Socket根据消息头tagHeader结构中的type字段辨识消息类型:

若type=LOGIN_IO,则表示有新成员加入或已有聊天成员下线退出,于是调用客户端UpdateUser()函数更新本地用户列表;若type=SEND_MESSAGE,则表示这是聊天室中其他成员发来的消息,调用GetMsgFromRoom()函数接收之后显示在客户端的屏幕上。

9.某个成员要下线时,单击“离开”按钮,关闭本地Socket。

10.一旦某成员退出,关闭了自己客户端程序的本地Socket,就会触发其在服务器上的Socket队列中对应的CClientSocket类对象的Onclose()事件,由CClientSocket类对象发消息通知其他成员有人退出,并调用UpdateUser()更新服务器用户列表。

11.当最后一个成员离开聊天室后,管理员可单击“关闭”按钮关闭服务器。

3.2主要控件的功能

服务器主要控件的功能见表3.1,客户端的主要控件功能见表3.2。

控件

功能

“管理员”文本框

配置管理员名称

IP控件

配置聊天室IP

“端口”文本框

配置聊天室端口

“聊天室动态”只读文本框

显示聊天室的动态,包括聊天室开启、关闭的提示信息,成员登录、离开的提示信息以及聊天消息

“用户在线”列表框

显示已进入聊天室的成员

“开启”按钮

开启聊天室

“关闭”按钮

关闭聊天室

“退出”按钮

退出

表3.1服务器的主要控件的功能

控件

功能

“您的昵称”文本框

配置昵称

IP控件

配置聊天室IP

“端口”文本框

配置聊天室端口

“在线好友”列表框

显示已进入聊天室的成员

“聊天”只读文本框

显示聊天室的动态,包括聊天室开启、关闭的提示信息,成员登录、离开的提示信息以及聊天消息

“发送”信息文本框

编辑要发送的消息

“发送”按钮

将消息发送出去

“进入”按钮

进入聊天室

“离开”按钮

离开聊天室

“退出”按钮

退出

表3.2客户端的主要控件功能

3.3程序流程图

(一)流程运行框架

图3.1流程运行框架程序流程图

(二)服务端

1.服务器“开启”按钮程序流程图如图3.2

图3.2服务器“开启”按钮程序流程图

2.客户端发送的消息到达服务器后,触发服务器Socket队列对应该客户端给的套接字的OnReceive()事件如图3.3

图3.3服务器OnReceive()事件程序流程图

3.服务器UpdateUser函数过程流程图如图3.4

图3.4服务器UpdateUser函数程序流程图

4.服务器OnClose()事件流程图如图3.5

图3.5服务器OnClose()事件流程图

(三)客户端

1.客户端“进入”按钮事件流程图如图3.6

图3.6客户端“进入”按钮事件程序流程图

2.客户端“发送”按钮事件流程图如图3.7

 

图3.7客户端“发送”按钮流程流程图

3.客户端本地OnReceive()事件流程图如图3.8

 

图3.8客户端本地OnReceive()事件流程图

4.客户端的GetMsgFromRoom()和UpdateUser()函数流程图如图3.9

 

图3.9客户端的GetMsgFromRoom()和UpdateUser()函数程序流程图

5.客户端的“离开”函数流程图如图3.10.

 

图3.10客户端的“离开”函数流程图

4具体代码实现

4.1服务器

1.单击“开启”按钮,添加函数:

voidCSelfRoomDlg:

:

OnButton1()

{

//TODO:

Addyourcontrolnotificationhandlercodehere

UpdateData();//刷新界面,获得用户输入

m_pSocket=newCServerSocket;

BYTEnFild[4];

CStringsIP;

ServerIP.GetAddress(nFild[0],nFild[1],nFild[2],nFild[3]);

//获取管理员配置的IP

sIP.Format("%d.%d.%d.%d",nFild[0],nFild[1],nFild[2],nFild[3]);

CTimetime=CTime:

:

GetCurrentTime();//获取当前时间

//下面开始输入完整性验证

if(m_strName.IsEmpty())

{

AfxMessageBox("请先登记管理员名!

");

return;

}

if(sIP.IsEmpty())

{

AfxMessageBox("请配置聊天室IP!

");

return;

}

if(sPort.IsEmpty())

{

AfxMessageBox("请配置要开放的窗口!

");

return;

}

//界面

m_Admin.EnableWindow(false);

ServerIP.EnableWindow(false);

ServerPort.EnableWindow(false);

m_Start.EnableWindow(false);

m_Stop.EnableWindow(true);

m_Exit.EnableWindow(false);

//开启聊天室,首先创建用于监听的套接字

if(m_pSocket->Create(atoi(sPort),1,sIP))

{

m_MessageList.SetWindowTextA("");

m_MessageList.ReplaceSel("聊天室开启成功!

\r\n");

CStringt=time.Format("%Y-%m-%d");

m_MessageList.ReplaceSel("日期:

"+t+"\r\n");

t=time.Format("%H:

%M:

%S");//获得聊天室开启的时刻信息

theApp.m_strName=m_strName;//记录管理员名

m_MessageList.ReplaceSel(t+"管理员"+theApp.m_strName+"开放聊天室\r\n");

}

if(m_pSocket->Listen())//监听开始

{

m_MessageList.ReplaceSel("等待成员加入…\r\n");

}//现在暂时还无人加入聊天,因此在线用户列表中仅管理员一人

m_UserList.ResetContent();

m_UserList.AddString(theApp.m_strName+"(管理员)");

this->SetWindowTextA("管理员:

"+m_strName+"-SelfRoom");

}

2.客户端用户发送消息到达服务器的OnReceive()事件:

voidCClientSocket:

:

OnReceive(intnErrorCode)

{

//TODO:

Addyourspecializedcodehereand/orcallthebaseclass

charbuff1[sizeof(Header)];

memset(buff1,0,sizeof(buff1));

Receive(buff1,sizeof(buff1));//首先接收信息的头部

this->AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE);

Header*header=(Header*)buff1;

intlength=header->len;

chartype=header->type;//解析头部内容

if(type==LOGIN_IO)//头部类型为LOGIN_IO,表示是新成员加入

{

charbuff[1000];

memset(buff,0,sizeof(buff));

Receive(buff,length);//继续接收这条信息的数据部分(新成员名)

this->AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE);

m_dlgServer->UpdateData();

CTimetime=CTime:

:

GetCurrentTime();

CStringt=time.Format("%H:

%M:

%S");

CEdit*p_Edit=(CEdit*):

:

AfxGetMainWnd()->GetDlgItem(IDC_EDIT_INFO);

//生成通知信息

CStringstrTemp=t+""+CString(buff)+"进入聊天室/\r\n";

p_Edit->ReplaceSel(strTemp);

m_strName=buff;//将新成员的用户名登记在服务器对应的Socket中

Headerhead;

head.type=SEND_MESSAGE;

head.len=strTemp.GetLength();

Headerhead_history;

head_history.type=SEND_MESSAGE;//生成"欢迎"信息

m_dlgServer->m_history+=m_strName+"欢迎您加入!

";

head_history.len=m_dlgServer->m_history.GetLength();

CClientSocket*curr=NULL;

POSITIONpos=clist->GetHeadPosition();

while(pos!

=NULL)

{

curr=(CClientSocket*)clist->GetNext(pos);

if(curr->m_strName==m_strName)//为新加入的那个成员发送欢迎信息

{

curr->Send((char*)&head_history,sizeof(Header));

curr->Send(m_dlgServer->m_history,m_dlgServer->m_history.GetLength());

}

else//向聊天室中其他的老成员发送通知信息,告知有新成员加入

{

curr->Send((char*)&head,sizeof(Header));

curr->Send(strTemp,strTemp.GetLength());

}

}

m_dlgServer->UpdateUser(this);//更新用户列表

}

if(type==SEND_MESSAGE)//头部类型为SEND_MESSAGE,表示是成员之间的聊天信息

{

charbuff[1000];

memset(buff,0,sizeof(buff));

Receive(buff,sizeof(buff));

this->AsyncSelect(FD_CLOSE|FD_READ|FD_WRITE);

CTimetime=CTime:

:

GetCurrentTime();

CStringt=time.Format("%H:

%M:

%S");

CStringnikeName=this->m_strName;

CStringstrTemp=t+""+nikeName+"说:

"+CString(buff)+"\r\n";

CStringstr=nikeName+""+t+"\r\n"+""+CString(buff);

CEdit*p_Edit=(CEdit*):

:

AfxGetMainWnd()->GetDlgItem(IDC_EDIT_INFO);

p_Edit->ReplaceSel(strTemp);

CClientSocket*curr=NULL;

POSITIONpos=clist->GetHeadPosition();

while(pos!

=NULL)//向聊天室内所有成员转发聊天信息内容

{

curr=(CClientSocket*)clist->GetNext(pos);

curr->Send((char*)header,sizeof(Header));

curr->Send(str,str.GetLength());

}

}

CSocket:

:

OnReceive(nErrorCode);

CSocket:

:

OnReceive(nErrorCode);

}

3.服务器检测到新成员加入,调用UpdateUser()函数更新用户列表:

voidCSelfRoomDlg:

:

UpdateUser(CClientSocket*pSocket)

{

m_UserList.ResetContent();

m_UserList.AddString(theApp.m_strName+"管理员");

CStringuser_info;

user_info=theApp.m_strName+"(管理员)"+"&";

if(pSocket!

=NULL)

{

CClientSocket*pSock=NULL;

POSITIONpos=pSocket->clist->GetHeadPosition();

while(pos!

=NULL)

{

pSock=(CClientSocket*)pSocket->clist->GetNext(pos);

m_UserList.AddString(pSock->m_strName);

user_info+=(pSock->m_strName+"&");

}

Headerhead;

head.type=LOGIN_IO;

head.len=user_info.GetLength();

POSITIONpo=pSocket->clist->GetHeadPosition();

while(po!

=NULL)

{

pSock=(CClientSocket*)pSocket->clist->GetNext(po);

pSock->Send((char*)&head,sizeof(Header));

pSock->Send((LPCTSTR)user_info,user_info.GetLength());

}

}

}

4.成员退出,关闭自己的Socket,触发服务器的OnClose()事件:

voidCClientSocket:

:

OnClose(intnErrorCode)

{

//TODO:

Addyourspecializedcodehereand/orcallthebaseclass

POSITIONpos=clist->Find(this);

if(pos!

=NULL){

clist->RemoveAt(pos);//移除服务器Socket队列中的套接字

CTimetime=CTime:

:

GetCurrentTime();

CStringt=time.Format("%H:

%M:

%S");

CEdit*p_Edit=(CEdit*)m_dlgServer->GetDlgItem(IDC_EDIT_INFO);

CStringstrTemp=t+""+this->m_strName+"离开聊天室\r\n";

p_Edit->ReplaceSel(strTemp);

Headerhead;

head.type=SEND_MESSAGE;

head.len=strTemp.GetLength();

CClientSocket*curr=NULL;

POSITIONpos=clist->GetHeadPosition();

while(pos!

=NULL)//将此用户离开的消息告知其他成员

{

curr=(CClientSocket*)clist->GetNext(pos);

curr->Send((char*)&head,sizeof(Header));

curr->Send(strTemp,strTemp.GetLength());

}

m_dlgServer->UpdateUser(this);//更新服务器列表

this->Close();

deletethis;

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

当前位置:首页 > 自然科学 > 物理

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

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