西安邮电大学高级Inernet聊天程序报告.docx
- 文档编号:17177663
- 上传时间:2023-07-22
- 格式:DOCX
- 页数:33
- 大小:760.06KB
西安邮电大学高级Inernet聊天程序报告.docx
《西安邮电大学高级Inernet聊天程序报告.docx》由会员分享,可在线阅读,更多相关《西安邮电大学高级Inernet聊天程序报告.docx(33页珍藏版)》请在冰点文库上搜索。
西安邮电大学高级Inernet聊天程序报告
西安邮电大学
(计算机学院)
课内实验报告
实验名称:
网络聊天程序
专业名称:
软件工程
班级:
1101班
学生姓名:
学号(8位):
指导教师:
王文浪
实验日期:
2013年11月25日
一.实验目的及实验环境
1.实验目的
综合运用本课程及计算机网络的相关知识设计并实现一个网络聊天程序,熟练掌握Internet网络编程思想,通过实践复习巩固以往所学的理论知识,提高对所学知识的综合应用能力。
2.实验环境
MicrosoftVisualC++
二.实验内容
该系统要求完成聊天室的全过程,包括客户端和服务器两大部分的编程及其连接。
服务器端聊天程序负责接收和发送来自客户端的聊天信息。
客户端聊天程序负责建立和维护与服务器端的连接,向服务器发送本客户的聊天内容。
3.方案设计
1.可行性分析
此程序主要分为两部分:
服务器端和客户端。
服务器端用于提供一个网络端口,等待客户端发出请求,登录到此服务端,然后进行网络通讯和消息的转发。
客户端可通过服务器端的IP地址发送连接请求,然后登陆聊天室。
在服务器端的成员列表栏中会显示在线的所有人名单,有人退出聊天室,成员列表会自动除名。
服务器端同时也提供了成员之间的私聊功能,此时服务器端作为一个转发站,进行消息的转发。
整个程序的主体使用了CSocket类的方法,实现了网络通讯聊天。
先启动服务器端聊天程序,这时聊天服务器需要指定一个端口号。
客户端则根据这个端口号以及服务器的网络地址与服务器进行通信。
2.功能要求
支持多个客户端的连接,在服务器和多个客户端之间进行数据传输。
接收客户端发送的消息,并显示在一个列表框中。
在用户连接上后有提示,显示出连接的用户名字。
发送信息时可以显示聊天的所有记录。
3.系统主要功能及其描述
(1)服务器端聊天程序必须能够做3件事情:
服务器聊天程序要在待定的端口上等待来自聊天客户的连接请求,并且需要维护一个客户连接表,以记录所有成功的连接。
服务器聊天程序要及时接受从各个聊天客户发送过来的信息,然后把这些信息转发到一个或多个客户连接。
对于公共聊天室,服务器将把接受到的信息向除源端外的所有客户发送过去。
服务器还要监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相应的表项,并及时更新连接表。
这些要求可以通过CSocket类提供的功能实现。
从CSocket派生出两个类CListenSocket和CClientSocket,它们分别用来侦听客户的连接请求和建立与客户的连接。
服务器只需要一个侦听套接字CListenSocket,然后根据客户的连接请求动态创建客户套接字CClientSocket。
客户套接字的数量是不可预知的,因此需要一个列表来记录。
MFC的CPtrList类就能实现这种功能。
(2)客户端聊天程序需要完成以下几个功能:
客户端聊天程序要负责建立和维护与服务器的连接,通过获取用户的设置尝试与服务器的连接,并且随时检测连接的状态。
客户端聊天程序要把用户输入的信息及时发送到聊天服务器。
一般情况下,当用户输入一行信息并且按下回车键后聊天程序就要把这一行信息发送出去,才能及时地满足用户的交互需求。
要随时准备好接受来自服务器的信息,随时把接受到的信息显示出来,让用户及时看到对方的响应。
在用户退出聊天过程是要关闭与服务器的连接。
比较好的做法是提前通知服务器或者直接给服务器发送一条退出通知,使得服务器能够及时掌握客户端的连接状态,把对方客户的退出信息及时发送到对等实体上。
客户端聊天程序需要使用一个通过CSocket类派生出来的CChatSocket类来实现。
该套接字用来发送一个与服务器的连接请求和维持与服务器的连接,发送和接收聊天信息,完成上述各项功能。
四.测试数据及运行结果
1.Login服务器:
在启动聊天室服务端的时候,会出现图1的界面,该界面为服务器的登陆界面。
2.启动服务器:
在登陆页面的环境下,点击启动服务器按钮,即可创建一个新的服务器,服务器界面如图2所示。
图1图2
3.Login客户端:
在启动客户端服务端的时候,会出现图3的界面,该界面为客户端的连接界面。
图3
4.图4为创建张三客户端,输入用户名张三。
图4
5.图5为用户张三连接服务器界面,在输入用户名张三并点击确定后,出现如下界面。
6.图6为用户李四的连接界面,在李四连接后,张三和李四用户同时出现在用户列表内。
图5图6
7.图7为用户李四的连接界面,在王五8.服务器显示,在张三,李四,
连接后,张三,李四和王五用户同时出王五进入聊天室后的界面为图8。
现在用户列表内。
图7图8
9.开始聊天,群聊,客户端发送信息时的界面为图9。
10.图10为私聊界面。
张三与李四私聊,点击私聊选项,并发送私聊内容。
图9图10
11.图11为张三私聊界面,李四和张三私聊,张三能看到李四发送的内容。
12.图12为王五的界面显示,王五看不到张三和李四的私聊内容。
图11图12
五.总结
1.实验过程中遇到的问题及解决办法;
在实验过程中,程序明明可以运行,但是就是无法出现连接的显示和状态。
最后与同学讨论后,才知道是服务器端有了错误,没有设置自己的IP地址,然后对于客户端进行了一番修改,才终于出现了上述的结果。
2.对设计及调试过程的心得体会。
该次设计的制作,我主要是参照了图书馆内的相关书籍,找到一个类似的程序,然后按照书上的内容一步步的做出来的。
虽然这个程序算不上是我自己写出来的,但通过这样的一个过程,还是让我学会了很多东西,也算能比较熟练地掌握MFC这一个软件了,这也算是一个不小的收获吧。
而且,在做这个程序的过程中,我认识到了遇到解决不了的问题与同学的讨论是很重要的。
在设计过程中,收获知识,提高能力的同时,我也学到了很多人生的哲理。
懂得怎么样去制定计划,怎么样去实现这个计划,并掌握了在执行过程中怎么样去克服心理上的不良情绪。
在以后的生活和学习的过程中,我一定会继续保持这种优良习惯。
通过这次实践,我发现我的编程能力还很薄弱,需要多多的练习。
这样才有可能让自己有信心,有动力,才能提高编程能力。
我相信自己以后会编写出让自己满意的程序和软件的。
6.附录:
源代码(电子版)
服务器端:
//ServerDlg.cpp:
implementationfile
//
#include"stdafx.h"
#include"Server.h"
#include"ServerDlg.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//CAboutDlgdialogusedforAppAbout
classCAboutDlg:
publicCDialog
{
public:
CAboutDlg();
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg:
:
CAboutDlg():
CDialog(CAboutDlg:
:
IDD)
{
}
voidCAboutDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CServerDlgdialog
CServerDlg:
:
CServerDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CServerDlg:
:
IDD,pParent)
{
m_hIcon=AfxGetApp()->LoadIcon(IDI_ICONAPP);
}
voidCServerDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
DDX_Control(pDX,IDC_LIST_USER,m_lbUser);
DDX_Text(pDX,IDC_EDIT_DISPLAY,m_strDisplay);
}
BEGIN_MESSAGE_MAP(CServerDlg,CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BN_START,OnBnStart)
ON_BN_CLICKED(IDC_BN_CLOSE,OnBnClose)
ON_MESSAGE(WM_RECEIVE,OnReceive)
ON_MESSAGE(WM_CLIENTCLOSE,OnClientClose)
ON_MESSAGE(WM_ACCEPT,OnAccept)
ON_WM_DESTROY()
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CServerDlgmessagehandlers
BOOLCServerDlg:
:
OnInitDialog()
{
CDialog:
:
OnInitDialog();
ASSERT((IDM_ABOUTBOX&0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
{
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,IDM_ABOUTBOX,strAboutMenu);
}
}
SetIcon(m_hIcon,TRUE);//Setbigicon
SetIcon(m_hIcon,FALSE);//Setsmallicon
m_iNetPort=3127;
m_Server.Initialize(this);
m_bServer=FALSE;
GetDlgItem(IDC_BN_CLOSE)->EnableWindow(FALSE);
returnTRUE;//returnTRUEunlessyousetthefocustoacontrol
}
voidCServerDlg:
:
OnSysCommand(UINTnID,LPARAMlParam)
{
if((nID&0xFFF0)==IDM_ABOUTBOX)
{
CAboutDlgdlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog:
:
OnSysCommand(nID,lParam);
}
}
voidCServerDlg:
:
OnPaint()
{
if(IsIconic())
{
CPaintDCdc(this);//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
dc.DrawIcon(x,y,m_hIcon);
}
else
{
CDialog:
:
OnPaint();
}
}
HCURSORCServerDlg:
:
OnQueryDragIcon()
{
return(HCURSOR)m_hIcon;
}
voidCServerDlg:
:
OnBnStart()
{
//创建套接字
m_Server.Create(m_iNetPort);
//开始监听
m_Server.Listen();
//显示
CStringstrInfo;
strInfo.LoadString(IDS_CREATE_SERVER);
ShowInDisplay(strInfo);
m_bServer=TRUE;
GetDlgItem(IDC_BN_START)->EnableWindow(FALSE);
GetDlgItem(IDC_BN_CLOSE)->EnableWindow(TRUE);
}
voidCServerDlg:
:
OnBnClose()
{
CloseServer();
GetDlgItem(IDC_BN_START)->EnableWindow(TRUE);
GetDlgItem(IDC_BN_CLOSE)->EnableWindow(FALSE);
}
voidCServerDlg:
:
OnAccept()
{
//创建新客户
CMySocket*pNewClient=newCMySocket;
pNewClient->Initialize(this);
m_Server.Accept(*pNewClient);
//放入链表中
m_lsClient.AddTail(pNewClient);
}
voidCServerDlg:
:
OnClientClose(WPARAMwParam,LPARAMlParam)
{
CMySocket*p_delClient=(CMySocket*)wParam;
//关闭该用户
p_delClient->ShutDown();
charbuffer[BUFFERSIZE];
while(p_delClient->Receive(buffer,BUFFERSIZE)>0);
p_delClient->Close();
//在用户链表中删除该用户
POSITIONpsCur,psList=m_lsClient.GetHeadPosition();
CMySocket*p_curClient;
while(psList!
=NULL)
{
psCur=psList;
p_curClient=(CMySocket*)m_lsClient.GetNext(psList);
if(p_delClient==p_curClient)
{
m_lsClient.RemoveAt(psCur);
break;
}
}
//发送信息告诉其他用户该客户退出
CStringstrMsg;
strMsg.LoadString(IDS_CLIENT_CLOSE);
NETMESSAGEnetMessage(PTC_CLIENT_QUIT,p_delClient->GetName(),_T(""),
p_delClient->GetName()+strMsg);
SendToAllClient(netMessage);
//界面上清理该用户信息
m_lbUser.DeleteString(m_lbUser.FindString(-1,p_delClient->GetName()));
ShowInDisplay(p_delClient->GetName()+strMsg);
//删除该用户
deletep_delClient;
}
voidCServerDlg:
:
OnReceive(WPARAMwParam,LPARAMlParam)
{
CMySocket*p_curClient=(CMySocket*)wParam;
NETMESSAGEnetMessage;
p_curClient->Receive((char*)&netMessage,sizeof(netMessage));
switch(netMessage.type)
{
casePTC_NEW:
//新客户加入
NewClientAdd(p_curClient,&netMessage);
break;
casePTC_SAY:
//普通聊天
ShowMessage(netMessage);
break;
}
//把加工过的信息发送给其他用户
SendToAllClient(netMessage);
}
voidCServerDlg:
:
CloseServer()
{
if(!
m_bServer)return;
//向所有客户发送服务端关闭的信息
CStringstrInfo;
strInfo.LoadString(IDS_CLOSESERVER);
NETMESSAGEnetMessage(PTC_SYSTEM,_T(""),_T(""),strInfo);
SendToAllClient(netMessage);
//服务端界面显示关闭信息
ShowInDisplay(strInfo);
//关闭服务端
m_Server.Close();
//关闭客户端
charbuffer[BUFFERSIZE];
CMySocket*m_pClient;
POSITIONpsList=m_lsClient.GetHeadPosition();
while(psList!
=NULL)
{
m_pClient=(CMySocket*)m_lsClient.GetNext(psList);
m_pClient->ShutDown();
while(m_pClient->Receive(buffer,BUFFERSIZE)>0);
m_pClient->Close();
deletem_pClient;
}
m_lsClient.RemoveAll();
m_bServer=FALSE;
}
//向所有户发出信息
voidCServerDlg:
:
SendToAllClient(constNETMESSAGE&netMessage)
{
CMySocket*m_pClient;
POSITIONpsList=m_lsClient.GetHeadPosition();
while(psList!
=NULL)
{
m_pClient=(CMySocket*)m_lsClient.GetNext(psList);
m_pClient->SendMsg(netMessage);
}
}
voidCServerDlg:
:
ShowInDisplay(CStringstr)
{
m_strDisplay+=str+"\r\n";
UpdateData(false);
}
voidCServerDlg:
:
OnDestroy()
{
CDialog:
:
OnDestroy();
//TODO:
Addyourmessagehandlercodehere
}
//新用户加入
voidCServerDlg:
:
NewClientAdd(CMySocket*p_client,NETMESSAGE*netMessage)
{
//存入用户名字
p_client->SetName(netMessage->form);
//在列表框中显示该用户
m_lbUser.AddString(p_client->GetName());
//发送用户列表给该客户
NETMESSAGEnetMsg(PTC_USER_LIST,_T(""),_T(""),_T(""));
intiListLen=m_lbUser.GetCount();
CStringstrMsg;
for(intindex=m_lbUser.GetTopIndex();index { m_lbUser.GetText(index,strMsg); strcpy(netMsg.data,(LPCTSTR)strMsg); p_client->SendMsg(netMsg); } //加工信息 strMsg.LoadString(IDS_NEW_CLIENT); strMsg=p_client->GetName()+strMsg; strcpy(netMessage->data,(LPCTSTR)strMsg); //显示该用户进入 ShowInDisplay(strMsg); } //显示普通消息 voidCServerDlg: : ShowMessage(NETMESSAGEnetMessage) { CStringstrTo=netMessage.to; if(strTo==_T("")) { strTo="所有人"; } CStringstrForm=netMessage.form; CStringstrMsg=netMessage.data; CStringstrOut=strForm+"对"+strTo+"说: "+strMsg; ShowInDisplay(strOut); } 客户端: //ClientDlg.cpp: implementationfile // #include"stdafx.h" #include"Client.h" #include"ClientDlg.h" #ifdef_DEBUG #definenewDEBUG_NEW #undefTHIS_FILE staticcharTHIS_FILE[]=__FILE__; #endif /////////////////////////////////////////////////////////////////////////////
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 西安 邮电大学 高级 Inernet 聊天 程序 报告
![提示](https://static.bingdoc.com/images/bang_tan.gif)