1、网络编程课程设计聊天室程序设计网络编程课程设计题 目:简单的聊天室程序专 业:计算机网络班 级:网络一班 时 间:2011.5.05摘要3一 设计内容.31、设计目的32、设计要求3二 设计原理3三 设计过程.41、程序设计流程及源代码.4(1)流程图.4(2)源代码.4I服务器4II客户端.92、调试分析过程描述143、结果分析19结论.20参考文献.20摘要当今世界正处于信息时代,计算机和通信网络是这一时代所谓“信息基础设施”。在互联网相当普及的今天,在互联网上聊天对很多“网虫”来说已经是家常便饭了。聊天室程序可以说是网上最简单的多点通信程序。一个简单的聊天室, 从程序员的观点来看就是在多
2、个I/O端点之间实现多对多的通信。基于SOCKET的局域网通信是一种灵活的、易于实现的、低成本的方法。它可以运行在各种使用TCP/IP协议作为通讯协议的网络上。而在SOCKET API的帮助下,开发基于SOCKET的局域网通信软件也是易于实现的。正文一、设计内容1、设计的目的综合运用本课程及计算机网络的相关知识设计并实现一个网络应用程序,以Visual C+作为开发平台,通过实践复习巩固课堂所学的理论知识,提高对所学知识的综合应用能力。2、设计要求 采用客户/服务器模式,分为客户端程序和服务器端程序。服务器采用WINSOCK I/O模型中的任一种,支持多个客户同时在线聊天。客户端程序和服务器程
3、序通过网络交换聊天字符串内容,服务器窗口的列表框中显示当前在线用户,支持客户端之间的私聊(可以通过服务器中转,或考虑UDP打洞直接建立端端连接)。二、设计原理服务器端通过socket()系统调用创建一个Socket数组后(即设定了接受连接客户的最大数目),与指定的本地端口绑定bind(),就可以在端口进行侦听listen()。如果有客户端连接请求,则在数组中选择一个空Socket,将客户端地址赋给这个Socket。然后登录成功的客户就可以在服务器上聊天了。客户端程序相对简单,只需要建立一个Socket与服务器端连接,成功后通过这个Socket来发送和接收数据就可以了。socket聊天室基本原理
4、是,抛开CGI(公共网关接口)和www服务器,根据html规范,接收到浏览器的请求以后,模仿www服务器的响应,将聊天内容发回浏览器。在浏览器看来就像浏览一个巨大的页面一样始终处于页面联接状态, 这就是一个专门的聊天服务器,一个简化了的www服务器。三、设计过程1、程序设计流程及源代码(1)流程图 (2)源代码 I服务器:/ ServerDlg.cpp : implementation file/#include stdafx.h#include Server.h#include ServerDlg.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_
5、FILEstatic char THIS_FILE = _FILE_;#endif/ CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialogpublic: CAboutDlg();protected: DECLARE_MESSAGE_MAP();CAboutDlg:CAboutDlg() : CDialog(CAboutDlg:IDD)void CAboutDlg:DoDataExchange(CDataExchange* pDX) CDialog:DoDataExchange(pDX);BEGIN_MESSAGE
6、_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) CDialog:DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST_USER, m_
7、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, OnClientClos
8、e) 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-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMen
9、u); SetIcon(m_hIcon, TRUE); / Set big icon SetIcon(m_hIcon, FALSE); / Set small icon m_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 controlvoid CServerDlg:OnSysCommand(UINT nID, L
10、PARAM lParam) if (nID & 0xFFF0) = IDM_ABOUTBOX) CAboutDlg dlgAbout; dlgAbout.DoModal(); else CDialog:OnSysCommand(nID, lParam); void CServerDlg:OnPaint() if (IsIconic() CPaintDC dc(this); / device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); int cxIcon = GetSyste
11、mMetrics(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); else CDialog:OnPaint(); HCURSOR CServerDlg:OnQueryDragIcon() return (HCURSOR) m_hIcon;void C
12、ServerDlg: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 CServerDlg:OnBnCl
13、ose() 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:O
14、nClientClose(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_curCl
15、ient; 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
16、_delClient-GetName() + 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 = (C
17、MySocket*)wParam; NETMESSAGE 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 CSe
18、rverDlg:CloseServer() if(!m_bServer) return; / 向所有客户发送服务端关闭的信息 CString strInfo; strInfo.LoadString(IDS_CLOSESERVER); NETMESSAGE netMessage(PTC_SYSTEM, _T(), _T(), strInfo); SendToAllClient(netMessage); / 服务端界面显示关闭信息 ShowInDisplay(strInfo); / 关闭服务端 m_Server.Close(); / 关闭客户端 char bufferBUFFERSIZE; CMy
19、Socket *m_pClient; POSITION psList = 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(); delete m_pClient; m_lsClient.RemoveAll(); m_bServer = FALSE;/ 向所有户发出信息vo
20、id CServerDlg:SendToAllClient(const NETMESSAGE &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 + r
21、n; UpdateData(false);void CServerDlg:OnDestroy() CDialog: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(); / 发送用户列表给该
22、客户 NETMESSAGE netMsg(PTC_USER_LIST, _T(), _T(), _T(); int iListLen = 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); / 显示该用户进入 Sh
23、owInDisplay(strMsg);/ 显示普通消息void CServerDlg:ShowMessage(NETMESSAGE netMessage) 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.cp
24、p : implementation file/#include stdafx.h#include Client.h#include ClientDlg.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialogpublic: CAboutDlg(); enum IDD = IDD_ABOUTBOX ; protected: virtual
25、void DoDataExchange(CDataExchange* pDX); / DDX/DDV supportprotected: DECLARE_MESSAGE_MAP();CAboutDlg:CAboutDlg() : CDialog(CAboutDlg:IDD)void CAboutDlg:DoDataExchange(CDataExchange* pDX) CDialog:DoDataExchange(pDX);BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)END_MESSAGE_MAP()/ CClientDlg dialogCClientDlg:C
26、ClientDlg(CWnd* pParent /*=NULL*/) : CDialog(CClientDlg:IDD, pParent) m_strDisplay = _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
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1