




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、网络程序设计课程设计报告书题 目:专 业:题目及要求1、简单的聊天室程序本题是一个简单的聊天室程序,采用客户 /服务器模式,分为客户端程序和 服务器端程序。由于服务器只能支持一个客户, 实际上是一个点对点通信的程序。 客户端程序和服务器程序通过网络交换聊天字符串内容, 并在窗口的列表框中显 示。本实例程序的技术要点是:如何从Casy ncSocket类派生出自己的 Win Sock类。理解 WinSock 类与应用程序框架的关系。 重点学习流式套接字对象的使用。 处理网络事件的方法。二,需求分析2.1 设计目的综合运用本课程及计算机网络的相关知识设计并实现一个网络应用程序, 以 Visual
2、C+乍为开发平台,通过实践复习巩固课堂所学的理论知识,提高对所学 知识的综合应用能力。2.2 设计要求采用客户 / 服务器模式,分为客户端程序和服务器端程序。服务器采用 WINSOCIK/O 模型中的任一种,支持多个客户同时在线聊天。客户端程序和服务 器程序通过网络交换聊天字符串内容,服务器窗口的列表框中显示当前在线用 户,支持客户端之间的私聊(可以通过服务器中转,或考虑UDP丁洞直接建立端 端连接)。课程设计要求设计并编程完成两个方面的内容:首先建立一个使用 TCP 协 议的聊天室服务器, 这个服务器可以同时支持多个用户的在线聊天; 其次设计一 个可以和服务器通信的聊天室客户端。2.3 功能
3、要求支持多个客户端的连接,在服务器和多个客户端之间进行数据传输;接收客户端发送的消息,并显示在一个列表框中; 在用户连接上后有提示,显示出连接的用户名字; 发送信息时可以显示聊天的所有记录;2.4 系统主要功能和主要功能描述:服务器端聊天程序必须能够做 3 件事情:( 1) 服务器聊天程序要在待定的端口上等待来自聊天客户的连接请求, 并且需 要维护一个客户连接表,以记录所有成功的连接。( 2) 服务器聊天程序要及时接受从各个聊天客户发送过来的信息, 然后把这些 信息转发到一个或多个客户连接。 对于公共聊天室, 服务器将把接受到的 信息向除源端外的所有客户发送过去。( 3) 服务器还要监控这些连
4、接的状态, 在客户主动离开或发生故障时从列表中 删除相应的表项,并及时更新连接表。这些要求可以通过 CSocket 类提供的功能实现。从 CSocket 派生出两个类 CListenSocket 和 CClientSocket, 它们分别用来侦听客户的连接请求和建立与 客户的连接。服务器只需要一个侦听套接字 CListenSocket ,然后根据客户的连 接请求动态创建客户套接字 CClientSocket 。客户套接字的数量是不可预知的, 因此需要一个列表来记录。MFC的CPtrList类就能实现这种功能。客户端聊天程序需要完成以下几个功能:( 1) 客户端聊天程序要负责建立和维护与服务器的
5、连接,通过获取用户的设 置尝试与服务器的连接,并且随时检测连接的状态。( 2) 客户端聊天程序要把用户输入的信息及时发送到聊天服务器。一般情况 下,当用户输入一行信息并且按下回车键后聊天程序就要把这一行信息 发送出去,才能及时地满足用户的交互需求。( 3) 要随时准备好接受来自服务器的信息,随时把接受到的信息显示出来, 让用户及时看到对方的响应。( 4) 在用户退出聊天过程是要关闭与服务器的连接。比较好的做法是提前通知服务器或者直接给服务器发送一条退出通知,使得服务器能够及时掌握客户端的连接状态,把对方客户的退出信息及时发送到对等实体上。客户端聊天程序需要使用一个通过 CSocket类派生出来
6、的CChatSocket类来 实现。该套接字用来发送一个与服务器的连接请求和维持与服务器的连接,发 送和接收聊天信息,完成上述各项功能。3设计流程图根据对用户的要求及功能设置可以得到以下的流程图 3.1,用户首先启动客 户端,登陆服务器并向服务器发送信息,启动服务器,服务器等待客户要求并 向客户反馈在线用户信息,用户向服务器发送信息,服务器处理用户的数据, 然后用户开始聊天。客户端的聊天分为对所有人的信息和私聊的信息,该信息 应通过程序控制分别进行处理。图3.1设计流程图5 设计的总结和体会该次课程设计的制作我主要是参照了图书馆内的相关书籍, 找到一个类似的 程序,然后按照书上的内容一步步的做
7、出来了, 虽然这个程序算不上是我自己写 出来的,但通过这样的一个过程, 还是让我学会了很多东西, 也算能比较熟练地 掌握 MFC 这一个软件了,这算是一个不小的收获吧,而且,在做这个程序的过 程中,让我认识到了在做这样程序中, 遇到解决不了的问题与同学的讨论时很重 要的,譬如可以以运行, 但是就是无法出现连接的显示和状态。 最后与同学讨论 后,才知道是服务器端有了错误,没有设置自己的 IP 地址,然后对于客户端进 行了一番修改, 才终于出现了上述的结果。 虽然没有彻底做的出来, 但是还是比 较开心的,因为自己知道了哪里不足, 哪里不可以, 可以在以后多多的做练习来 充实自己。在课程设计过程中,
8、收获知识,提高能力的同时,我也学到了很多人生的 哲理,懂得怎么样去制定计划, 怎么样去实现这个计划, 并掌握了在执行过程中 怎么样去克服心理上的不良情绪。 因此在以后的生活和学习的过程中, 我一定会 把课程设计的精神带到生活中,不畏艰难,勇往直前!我以后还是需要多多的练习, 多多的勤奋, 这样才有可能让自己有信心, 有 动力,让自己不至于懂的太少而怯场, 因为不懂而不会做, 相信自己以后会编写 出让自己满意的程序和软件的。附:源代码I 服务器:/ ServerDlg.cpp : implementation file/#include stdafx.h#include Server.h#inc
9、lude ServerDlg.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif / CAboutDlg dialog used for App About class CAboutDlg : public CDialog public:CAboutDlg();protected:DECLARE_MESSAGE_MAP();CAboutDlg:CAboutDlg() : CDialog(CAboutDlg:IDD)void CAboutDlg:DoDataExchang
10、e(CDataExchange* pDX) CDialog:DoDataExchange(pDX);BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)END_MESSAGE_MAP()/ CServerDlg dialogCServerDlg:CServerDlg(CWnd* pParent /*=NULL*/): CDialog(CServerDlg:IDD, pParent)m_hIcon = AfxGetApp()-LoadIcon(IDI_ICONAPP);void CServerDlg:DoDataExchange(CDataExchange* pDX)CDi
11、alog: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_RECEI
12、VE, OnReceive)ON_MESSAGE(WM_CLIENTCLOSE, OnClientClose)ON_MESSAGE(WM_ACCEPT, OnAccept)ON_WM_DESTROY()END_MESSAGE_MAP()/ CServerDlg message handlersBOOL CServerDlg:OnInitDialog()CDialog:OnInitDialog();ASSERT(IDM_ABOUTBOX & 0xFFF0) = IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR); pSysMenu
13、-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);SetIcon(m_hIcon, TRUE); / Set big iconSetIcon(m_hIcon, FALSE);/ Set small iconm_iNetPort = 3127;m_Server.Initialize(this);m_bServer = FALSE;GetDlgItem(IDC_BN_CLOSE)-EnableWindow(FALSE);return TRUE; / return TRUE unless you set the focus to a control
14、 void CServerDlg:OnSysCommand(UINT nID, LPARAM lParam) if (nID & 0xFFF0) = IDM_ABOUTBOX)CAboutDlg dlgAbout;dlgAbout.DoModal();elseCDialog:OnSysCommand(nID, lParam);void CServerDlg:OnPaint()if (IsIconic()CPaintDC dc(this); / device context for paintingdc.GetSafeHdc(),SendMessage(WM_ICONERASEBKGND, (W
15、PARAM) 0);int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2; dc.DrawIcon(x, y, m_hIcon);elseCDialog:OnPaint();HCURSOR CServerDlg:OnQueryDragIcon()return (H
16、CURSOR) m_hIcon;void CServerDlg:OnBnStart()/ 创建套接字m_Server.Create(m_iNetPort);/ 开始监听m_Server.Listen();/ 显示CString strInfo;strInfo.LoadString(IDS_CREATE_SERVER);ShowInDisplay(strInfo);m_bServer = TRUE;GetDlgItem(IDC_BN_START)-EnableWindow(FALSE);GetDlgItem(IDC_BN_CLOSE)-EnableWindow(TRUE);void CServe
17、rDlg:OnBnClose()CloseServer();GetDlgItem(IDC_BN_START)-EnableWindow(TRUE);GetDlgItem(IDC_BN_CLOSE)-EnableWindow(FALSE);void CServerDlg:OnAccept()/ 创建新客户CMySocket *pNewClient = new CMySocket;pNewClient-Initialize(this);m_Server.Accept(*pNewClient);/ 放入链表中m_lsClient.AddTail(pNewClient);void CServerDlg
18、:OnClientClose(WPARAM wParam, LPARAM lParam)CMySocket *p_delClient = (CMySocket*)wParam;/ 关闭该用户 p_delClient-ShutDown();char bufferBUFFERSIZE;while(p_delClient-Receive(buffer, BUFFERSIZE)0); p_delClient-Close();/ 在用户链表中删除该用户POSITION psCur, psList = m_lsClient.GetHeadPosition();CMySocket *p_curClient;
19、while(psList!=NULL)psCur = psList;p_curClient = (CMySocket *)m_lsClient.GetNext(psList); if(p_delClient=p_curClient)m_lsClient.RemoveAt(psCur);break;/ 发送信息告诉其他用户该客户退出CString strMsg; strMsg.LoadString(IDS_CLIENT_CLOSE);NETMESSAGE netMessage(PTC_CLIENT_QUIT, p_delClient-GetName(), _T(), p_delClient-Ge
20、tName() + strMsg);SendToAllClient(netMessage);/ 界面上清理该用户信息m_lbUser.DeleteString(m_lbUser.FindString(-1, p_delClient-GetName();ShowInDisplay(p_delClient-GetName() + strMsg);/ 删除该用户delete p_delClient;void CServerDlg:OnReceive(WPARAM wParam, LPARAM lParam)CMySocket *p_curClient = (CMySocket*)wParam;NET
21、MESSAGE netMessage;p_curClient-Receive(char *)&netMessage, sizeof(netMessage); switch(netMessage.type)case PTC_NEW: / 新客户加入 NewClientAdd(p_curClient, &netMessage); break;case PTC_SAY: / 普通聊天ShowMessage(netMessage);break;/ 把加工过的信息发送给其他用户 SendToAllClient(netMessage);void CServerDlg:CloseServer()if(!m_
22、bServer) return;/ 向所有客户发送服务端关闭的信息CString strInfo; strInfo.LoadString(IDS_CLOSESERVER);NETMESSAGE netMessage(PTC_SYSTEM, _T(), _T(), strInfo); SendToAllClient(netMessage);/ 服务端界面显示关闭信息ShowInDisplay(strInfo);/ 关闭服务端m_Server.Close();/ 关闭客户端char bufferBUFFERSIZE;CMySocket *m_pClient;POSITION psList = m_
23、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();delete m_pClient;m_lsClient.RemoveAll();m_bServer = FALSE;/ 向所有户发出信息void CServerDlg:SendToAllClient(const NETMESSAGE
24、&netMessage)CMySocket *m_pClient;POSITION psList = m_lsClient.GetHeadPosition();while(psList!=NULL)m_pClient = (CMySocket *)m_lsClient.GetNext(psList);m_pClient-SendMsg(netMessage);void CServerDlg:ShowInDisplay(CString str)m_strDisplay += str + rn;UpdateData(false);void CServerDlg:OnDestroy()CDialog
25、:OnDestroy();/ TODO: Add your message handler code here/ 新用户加入void CServerDlg:NewClientAdd(CMySocket *p_client, NETMESSAGE *netMessage)/ 存入用户名字 p_client-SetName(netMessage-form);/ 在列表框中显示该用户 m_lbUser.AddString(p_client-GetName();/ 发送用户列表给该客户NETMESSAGE netMsg(PTC_USER_LIST, _T(), _T(), _T();int iList
26、Len = m_lbUser.GetCount();CString strMsg;for(int index=m_lbUser.GetTopIndex(); indexSendMsg(netMsg);/ 加工信息strMsg.LoadString(IDS_NEW_CLIENT); strMsg = p_client-GetName() + strMsg; strcpy(netMessage-data, (LPCTSTR)strMsg);/ 显示该用户进入ShowInDisplay(strMsg);/ 显示普通消息void CServerDlg:ShowMessage(NETMESSAGE ne
27、tMessage) CString strTo = netMessage.to;if(strTo=_T()strTo = 所有人 ;CString strForm = netMessage.form;CString strMsg = netMessage.data;CString strOut = strForm + 对 + strTo + 说: + strMsg;ShowInDisplay(strOut);II 客户端:/ ClientDlg.cpp : implementation file/#include stdafx.h#include Client.h#include Client
28、Dlg.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ CAboutDlg dialog used for App About class CAboutDlg : public CDialog public:CAboutDlg(); enum IDD = IDD_ABOUTBOX ;protected:/ DDX/DDV supportvirtual void DoDataExchange(CDataExchange* pDX); protected:DECLAR
29、E_MESSAGE_MAP();CAboutDlg:CAboutDlg() : CDialog(CAboutDlg:IDD)void CAboutDlg:DoDataExchange(CDataExchange* pDX) CDialog:DoDataExchange(pDX); BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP()/ CClientDlg dialog CClientDlg:CClientDlg(CWnd* pParent /*=NULL*/): CDialog(CClientDlg:IDD, pParent)m_st
30、rDisplay = _T(); m_strSend = _T(); m_bWhispering = FALSE;m_hIcon = AfxGetApp()-LoadIcon(IDR_MAINFRAME);void CClientDlg: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_SEND,
31、 m_strSend);DDX_Check(pDX, IDC_CHECK_WHISPERING , m_bWhispering); BEGIN_MESSAGE_MAP(CClientDlg, CDialog)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BN_CONNECT, OnBnConnect)ON_BN_CLICKED(IDC_BN_CLOSE, OnBnClose)ON_BN_CLICKED(IDC_BN_SEND, OnBnSend) ON_MESSAGE(WM_RECEIVE, OnRe
32、ceive) ON_MESSAGE(WM_SOCKETCLOSE, OnServerClose) ON_MESSAGE(WM_SEND, OnSend) ON_MESSAGE(WM_CONNCET, OnConnect) ON_LBN_DBLCLK(IDC_LIST_USER, OnDblclkListUser) END_MESSAGE_MAP() / CClientDlg message handlersBOOL CClientDlg:OnInitDialog()CDialog:OnInitDialog();ASSERT(IDM_ABOUTBOX & 0xFFF0) = IDM_ABOUTB
33、OX);ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR);pSysMenu-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);SetIcon(m_hIcon, TRUE); / Set big iconSetIcon(m_hIcon, FALSE);/ Set small icon/ 参数初始化m_Socket.Initialize(this);m_strNetIP = _T(127.0.0.1);m_iNetPort = 3127;m_bConnect = FALSE;GetDlgItem(IDC_BN
34、_CLOSE)-EnableWindow(FALSE);GetDlgItem(IDC_BN_SEND)-EnableWindow(FALSE);return TRUE; / return TRUE unless you set the focus to a controlvoid CClientDlg:OnSysCommand(UINT nID, LPARAM lParam)if (nID & 0xFFF0) = IDM_ABOUTBOX)CAboutDlg dlgAbout;dlgAbout.DoModal();elseCDialog:OnSysCommand(nID, lParam);vo
35、id CClientDlg:OnPaint()if (IsIconic()CPaintDC dc(this); / device context for paintingdc.GetSafeHdc(),SendMessage(WM_ICONERASEBKGND, (WPARAM) 0);int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;in
36、t y = (rect.Height() - cyIcon + 1) / 2; dc.DrawIcon(x, y, m_hIcon);elseCDialog:OnPaint();HCURSOR CClientDlg:OnQueryDragIcon()return (HCURSOR) m_hIcon;void CClientDlg:OnBnConnect()CString strConnectError;/ 获取用户名字CInputDlg inputDlg;int iResult = inputDlg.DoModal(); if(iResult=IDCANCEL)return; m_strNam
37、e = inputDlg.m_strName;/ 创建套接字 if(!m_Socket.Create()strConnectError.LoadString(IDS_FAIL_CREATE_SOCKET); ShowInDisplay(strConnectError);return;CString strInfo;strInfo.LoadString(IDS_CONNECTING); ShowInDisplay(strInfo);/ 连接服务器 if(!m_Socket.Connect(m_strNetIP, m_iNetPort) int n = m_Socket.GetLastError(
38、); strConnectError.LoadString(IDS_FAIL_CONNECT); ShowInDisplay(strConnectError);return; strInfo.LoadString(IDS_SUCCEED_CONNECT); ShowInDisplay(strInfo);m_bConnect = TRUE;/ 发送自已的名字NETMESSAGE netMessage(PTC_NEW, m_strName, _T(), _T(); m_Socket.SendMsg(netMessage);GetDlgItem(IDC_BN_CONNECT)-EnableWindo
39、w(FALSE);GetDlgItem(IDC_BN_CLOSE)-EnableWindow(TRUE);GetDlgItem(IDC_BN_SEND)-EnableWindow(TRUE);void CClientDlg:OnBnClose()if(m_bConnect)m_Socket.Close();m_bConnect = FALSE;GetDlgItem(IDC_BN_CONNECT)-EnableWindow(TRUE);GetDlgItem(IDC_BN_CLOSE)-EnableWindow(FALSE);GetDlgItem(IDC_BN_SEND)-EnableWindow
40、(FALSE); m_lbUser.ResetContent();CString strMsg;strMsg.LoadString(IDS_BREAK);ShowInDisplay(strMsg);void CClientDlg:OnBnSend()OnSend();m_strSend = _T();UpdateData(FALSE);void CClientDlg:OnReceive()NETMESSAGE netMessage;m_Socket.Receive(char *)&netMessage, sizeof(netMessage);CString strForm = netMessa
41、ge.form;/ 过滤自已发出的信息if(strForm=m_strName) return;CString strTo = netMessage.to;CString strMsg = netMessage.data;switch(netMessage.type)case PTC_USER_LIST: / 用户列表 m_lbUser.AddString(strMsg);break;case PTC_NEW: / 新用户进入 m_lbUser.AddString(strForm); ShowInDisplay(strMsg);break;case PTC_SAY: ShowMessage(netMessage);case PTC_WHISPERING: / 密语 if(strTo!=m_strName) return; ShowMessage(netMessage);break;case PTC_CLIENT_QUIT: / 有用户退出m_lbUser.DeleteString(m_lbUser.FindString(-1, strForm); ShowInDisplay(strMsg);break;void CClientDlg:OnServerClose()if(!m_bConnect) return;CString strMsg
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年事业单位工勤技能-河北-河北兽医防治员四级(中级工)历年参考题库含答案解析
- 2025年事业单位工勤技能-江西-江西图书资料员四级(中级工)历年参考题库含答案解析(5套)
- 2025年事业单位工勤技能-江苏-江苏热力运行工四级(中级工)历年参考题库含答案解析(5套)
- 2025年事业单位工勤技能-新疆-新疆热处理工五级(初级工)历年参考题库含答案解析(5套)
- 2025年事业单位工勤技能-广西-广西经济岗位工三级(高级工)历年参考题库典型考点含答案解析
- 2025年事业单位工勤技能-广西-广西家禽饲养员一级(高级技师)历年参考题库典型考点含答案解析
- 2025年事业单位工勤技能-广西-广西动物检疫员五级(初级工)历年参考题库典型考点含答案解析
- 2025年事业单位工勤技能-广东-广东水工监测工二级(技师)历年参考题库含答案解析
- 2020-2025年注册岩土工程师之岩土专业知识通关考试题库带答案解析
- 2025年事业单位工勤技能-安徽-安徽医技工四级(中级工)历年参考题库典型考点含答案解析
- 七年级道德与法治第九课增强安全意识
- 乡村振兴培训试题及答案
- CJ/T 486-2015土壤固化外加剂
- 冻伤急救护理
- 设备日常维护保养记录表
- 跨境电商代运营合同协议
- 借车免责协议书合同
- 空乘中外民俗试题及答案
- 德州市星邦日用品有限公司年产300吨PVA塑料胶棉项目环境影响报告表
- 电气检测维保合同协议
- 石墨烯材料企业数字化转型与智慧升级战略研究报告
评论
0/150
提交评论