网络编程课程设计聊天室程序设计.docx
《网络编程课程设计聊天室程序设计.docx》由会员分享,可在线阅读,更多相关《网络编程课程设计聊天室程序设计.docx(28页珍藏版)》请在冰豆网上搜索。
网络编程课程设计聊天室程序设计
网络编程课程设计
题目:
简单的聊天室程序
专业:
计算机网络
班级:
网络一班
时间:
2011.5.05
[摘要]…………………………………………………………………3
一设计内容…………………………………………………………..3
1、设计目的……………………………………………………………………3
2、设计要求……………………………………………………………………3
二设计原理……………………………………………………………3
三设计过程…………………………………………………………….4
1、程序设计流程及源代码…………………………………………………….4
(1)流程图……………………………………………………………………….4
(2)源代码……………………………………………………………………….4
I服务器………………………………………………………………………4
II客户端……………………………………………………………………..9
2、调试分析过程描述……………………………………………………………14
3、结果分析………………………………………………………………………19
[结论]………………………………………………..………………….20
[参考文献]………………………………………………….…………..20
[摘要]
当今世界正处于信息时代,计算机和通信网络是这一时代所谓“信息基础设施”。
在互联网相当普及的今天,在互联网上聊天对很多“网虫”来说已经是家常便饭了。
聊天室程序可以说是网上最简单的多点通信程序。
一个简单的聊天室,从程序员的观点来看就是在多个I/O端点之间实现多对多的通信。
基于SOCKET的局域网通信是一种灵活的、易于实现的、低成本的方法。
它可以运行在各种使用TCP/IP协议作为通讯协议的网络上。
而在SOCKETAPI的帮助下,开发基于SOCKET的局域网通信软件也是易于实现的。
[正文]
一、设计内容
1、设计的目的
综合运用本课程及计算机网络的相关知识设计并实现一个网络应用程序,以VisualC++作为开发平台,通过实践复习巩固课堂所学的理论知识,提高对所学知识的综合应用能力。
2、设计要求
采用客户/服务器模式,分为客户端程序和服务器端程序。
服务器采用WINSOCKI/O模型中的任一种,支持多个客户同时在线聊天。
客户端程序和服务器程序通过网络交换聊天字符串内容,服务器窗口的列表框中显示当前在线用户,支持客户端之间的私聊(可以通过服务器中转,或考虑UDP打洞直接建立端端连接)。
二、设计原理
服务器端通过socket()系统调用创建一个Socket数组后(即设定了接受连接客户的最大数目),与指定的本地端口绑定bind(),就可以在端口进行侦听listen()。
如果有客户端连接请求,则在数组中选择一个空Socket,将客户端地址赋给这个Socket。
然后登录成功的客户就可以在服务器上聊天了。
客户端程序相对简单,只需要建立一个Socket与服务器端连接,成功后通过这个Socket来发送和接收数据就可以了。
socket聊天室基本原理是,抛开CGI(公共网关接口)和www服务器,根据html规范,接收到浏览器的请求以后,模仿www服务器的响应,将聊天内容发回浏览器。
在浏览器看来就像浏览一个巨大的页面一样始终处于页面联接状态,这就是一个专门的聊天服务器,一个简化了的www服务器。
三、设计过程
1、程序设计流程及源代码
(1)流程图
(2)源代码
I服务器:
//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);
}
II客户端:
//ClientDlg.cpp:
implementationfile
//
#include"stdafx.h"
#include"Client.h"
#include"ClientDlg.h"
#ifdef_DEBUG
#definenewDEBUG_NEW
#undefTHIS_FILE
staticcharTHIS_FILE[]=__FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//CAboutDlgdialogusedforAppAbout
classCAboutDlg:
publicCDialog
{
public:
CAboutDlg();
enum{IDD=IDD_ABOUTBOX};
protected:
virtualvoidDoDataExchange(CDataExchange*pDX);//DDX/DDVsupport
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg:
:
CAboutDlg():
CDialog(CAboutDlg:
:
IDD)
{
}
voidCAboutDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg,CDialog)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
//CClientDlgdialog
CClientDlg:
:
CClientDlg(CWnd*pParent/*=NULL*/)
:
CDialog(CClientDlg:
:
IDD,pParent)
{
m_strDisplay=_T("");
m_strSend=_T("");
m_bWhispering=FALSE;
m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
voidCClientDlg:
:
DoDataExchange(CDataExchange*pDX)
{
CDialog:
:
DoDataExchange(pDX);
DDX_Control(pDX,IDC_LIST_USER,m_lbUser);
DDX_Text(pDX,IDC_EDIT_DIAPLAY,m_strDisplay);
DDX_Text(pDX,IDC_EDIT