基于MFC的聊天程序设计
- 格式:doc
- 大小:206.50 KB
- 文档页数:9
聊天程序设计报告---- 网络编程设计报告目录【1】设计原理———————————————————————— 1 【2】功能描述———————————————————————— 1 【3】详细设计———————————————————————— 2 【4】工作进度————————————————————————7 【5】设计总结————————————————————————8 【6】使用方法————————————————————————9 【7】附录——————————————————————————9一. 设计原理计算机网络技术发展至今已经大大超越了人们当初的预想,无论是人们日常的工作还是学习,我们都越来越多的依靠到互联网。
各种实时性的聊天娱乐软件也同时诞生,而且为我们的即时通讯带来了众多的方便,比如说大家所熟知的腾讯QQ、微软的MSN、中国移动的Fetion 等,都是做的比较成功的实时聊天工具。
随着网络的日益普及,各种聊天工具也层出不穷,但当我们学习了《网络编程》这门课程之后,我们便会觉得,其实要实现简单的网络通讯其实并不难。
接下来的课程设计就是针对一个简单的网络聊天程序,利用MFC 为开发工具,实现基本的通讯功能。
此程序主要分为两个模块:服务线程和聊天线程。
服务线程用于提供一个网络端口,等待客户线程发出请求,登录到作为服务端的程序,然后进行网络通讯和消息的收发;客户端可通过服务器端的IP 地址发送连接请求,然后建立连接,进行通讯。
整个程序的主体使用了CSocket类的方法,实现了网络通讯聊天。
二.功能描述(需求分析)1、一对一会话。
此程序既可以作为服务器,也可以作为客户端。
当发起聊天请求时是客户端,而当接受连接请求时时服务器。
通讯基于可靠的TCP 连接。
2、修改联系人通讯地址。
可以根据联系人IP 地址和端口的不同建立不同的连接。
可以实时修改联系人的地址。
3、多线程技术。
进程启动时会开启一个专门用于监听连接请求的服务进程,线程函数为UINT threadListen(LPVOID lpParam) ,用来被动接受聊天请求。
MFC实现简单网络聊天程序MFC(Microsoft Foundation Classes)是微软公司提供的一个应用程序框架,用于开发Windows系统上的图形用户界面程序。
在此基础上,我们可以利用MFC来实现简单的网络聊天程序。
首先,我们需要创建一个MFC应用程序项目。
使用Visual Studio打开,选择MFC应用程序向导,选择对话框风格。
然后,设置对话框的布局,包括聊天消息显示框、消息输入框、发送按钮等控件。
接下来,我们需要使用Socket编程来实现网络通信功能。
MFC提供了CSocket类,我们可以使用它来处理数据的发送和接收。
在对话框类中添加成员变量m_socket,类型为CSocket。
在OnInitDialog函数中,我们需要创建Socket,并进行连接。
可以通过使用Create函数创建CSocket对象,并调用Connect函数来连接指定的地址和端口号。
例如,可以连接到本地主机上的一些端口,这样就可以进行本地测试。
然后,我们需要添加事件处理函数来处理发送和接收消息。
当发送按钮被点击时,可以通过调用Socket对象的Send函数将消息发送给服务器。
可以使用CString类来处理字符串数据。
当接收到消息时,可以通过调用Socket对象的Receive函数将消息接收到的缓冲区中。
为了提供实时地聊天消息显示功能,我们需要使用SetWindowText函数将数据显示到聊天消息显示框中。
当接收到消息时,可以将消息显示在聊天消息显示框中,同时可以使用UpdateData函数实时更新界面。
在程序结束时,我们需要断开连接并销毁Socket对象。
在析构函数中,可以调用Shutdown函数来关闭连接,然后销毁Socket对象。
除了基本的发送和接收消息功能,我们还可以添加一些其他的功能,比如可以使用菜单栏来选择连接和断开服务器,可以添加登录和注册功能等。
这些可以根据实际需求进行扩展。
总结起来,通过使用MFC应用程序框架和Socket编程,我们可以实现简单的网络聊天程序。
河海大学计算机及信息工程学院MFC课程设计报告题目聊天室程序设计学号专业授课班号学生姓名指导教师完成时间题目:设计一个聊天室系统,实现多人一起聊天。
一.引言1.1开发背景随着网络信息时代的来临,INTERNET应用越来越广泛,人们越来越习惯于在网上获取和交流信息。
据调查显示,80%以上的人上网都会打开聊天工具来聊天,而几乎每一个年轻人都会去聊天。
使用网上聊天已经成为现代年轻人一种新的交往方式。
聊天室更适合于陌生人之间进行较为主观、感兴化的讨论。
所以有大部分的人会进入聊天室聊天,它会给人一个完全自由的聊天世界。
因此我联系所学的MFC 知识,决定做一个简易的聊天室程序。
1.2开发环境以及运行环境1.2.1 开发环境●Intel® Pentium® 4 2.0GHz,512M内存,80G硬盘●Mi crosoft® Windows™ XP Professional●Microsoft® Visual C++ 6.01.2.2 运行环境●Intel® Pentium® 2及以上处理器,32M以上内存,4G以上硬盘●Microsoft® Windows™ XP操作系统●800*600或以上的屏幕分辨率二.需求分析1、用WINSOCK实现简单的网络聊天;2、在MFC开发平台上编写一个聊天系统;3、得server和client之间可以相互通信;4、多人能够发送信息至服务器,首先显示进入聊天室的成员名,然后显示对方名字和聊天信息,可以并发执行。
三、算法分析建立连接过程流程图如下:Server端Client端创建CClientSocket对象,在某个端口提供监听服务等待来自Client端的服务请求接受Client端的请求,用返回的CClientSocket建立连接向用CClientSocket连接建立的流中读写数据关闭CClientSocket,结束与当前Client的通信,等待其他请求关闭CClientSocket对象,结束监听服务创建CChatSocket对象,向Server的监听端口发出请求向用CChatSocket连接建立的流中读写数据关闭CChatSocket,结束与当前Server端的通信建立连接拆除链路数据通路四、详细设计程序个模块代码如下:1.客户端(1)通过AppWizard生成基于对话框的应用程序ChatClient,在向导的第二步选择WindowsSockets的支持,其余步骤均用默认值。
一. 设计原理计算机网络技术发展至今已经大大超越了人们当初的预想,无论是人们日常的工作还是学习,我们都越来越多的依靠到互联网。
各种实时性的聊天娱乐软件也同时诞生,而且为我们的即时通讯带来了众多的方便,比如说大家所熟知的腾讯QQ、微软的MSN、中国移动的Fetion等,都是做的比较成功的实时聊天工具。
随着网络的日益普及,各种聊天工具也层出不穷,但当我们学习了《网络编程》这门课程之后,我们便会觉得,其实要实现简单的网络通讯其实并不难。
接下来的课程设计就是针对一个简单的网络聊天程序,利用MFC为开发工具,实现基本的通讯功能。
此程序主要分为两个模块:服务线程和聊天线程。
服务线程用于提供一个网络端口,等待客户线程发出请求,登录到作为服务端的程序,然后进行网络通讯和消息的收发;客户端可通过服务器端的IP 地址发送连接请求,然后建立连接,进行通讯。
整个程序的主体使用了CSocket类的方法,实现了网络通讯聊天。
二.功能描述(需求分析)1、一对一会话。
此程序既可以作为服务器,也可以作为客户端。
当发起聊天请求时是客户端,而当接受连接请求时时服务器。
通讯基于可靠的TCP连接。
2、修改联系人通讯地址。
可以根据联系人IP地址和端口的不同建立不同的连接。
可以实时修改联系人的地址。
3、多线程技术。
进程启动时会开启一个专门用于监听连接请求的服务进程,线程函数为UINT threadListen(LPVOID lpParam),用来被动接受聊天请求。
无论是主动发起聊天请求还是被动接受连接请求,都将启动一个名为CIMTalking的线程,专门处理聊天业务。
4、整个程序的主体使用了基于CSocket类的网络编程方法,综合运用了CSocket、CSocketFile、CArchive等类的方法,实现了网络通讯聊天。
IM的功能可划分为以下几点:1)界面显示:将在线好友显示在好友列表中,并实现好友分组,便于选择联系人。
2)聊天功能:与好友聊天。
具体界面如下:(1)加载套接字库:BOOL AfxSocketInit(WSADATA* lpwsaData=NULL); Msdn中的AfxSocketInitRemarksCall this function in your CWinApp::InitInstance override to initialize Windows Sockets. 所以我们要再CWINApp下的InitInstance中加载套接字if(!AfxSocketInit()){AfxMessageBox("套接字库加载失败");return FALSE;}(2)在Dlg类中定义一个类型为BOOL的InitSocket函数,并且定义一个类型为SOCKET 的变量m_socket。
m_socket=socket(AF_INET,SOCK_DGRAM,0);if(INVALID_SOCKET==m_socket){MessageBox("套接字创建失败");return FALSE;}sockaddr_in addrsrv;addrsrv.sin_family=AF_INET;addrsrv.sin_port=htons(6000);addrsrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);nt reval;reval=bind(m_socket,(SOCKADDR *)&addrsrv,sizeof(SOCKADDR));if(reval==SOCKET_ERROR){closesocket(m_socket);MessageBox("绑定失败");return FALSE;}return TRUE;(3)在CXXDlg类下的OnInitDialog调用InitSocket,并且创建线程函数,用来接收数据。
因为recvfrom函数当没数据接收的时候会造成堵塞,所以我们采用线程函数来接收数据。
本系统基于客户端/服务器基本原理,程序即是服务端,也是客户端,通过IP就可以相互添加好友,并且实现点到点通信,有聊天记录(未实现根据用户发送的消息而改变字体颜色,只能在客户端改),字体颜色设置(一改全改~),包含主界面MaindBord和聊天Talk两大功能模块。
(1) MaindBord模块A、登录模块登陆模块的实现过程有下面几个步骤:(1)初始化列表信息,获取用户名,服务器的IP地址,使按键失效(2)确认登陆后创建套接字,绑定,监听(3)初始化成功后,激活添加好友和隐藏功能B、好友模块添加好友的实现过程有下面几个步骤:(1)弹出对话框(2)获取对话框中的IP(3)检查对方是否在线,建立连接(4)发送请求验证C、好友列表模块(1)客户接收请求,将服务端加入列表,发送客户端信息(2)服务端得到客户端信息,加入列表(3)双击好友列表,弹出发送信息对话框D、隐藏模块(1)隐藏与显示(2)响应鼠标,弹出控制菜单(2)聊天Talk模块A、发送信息模块聊天模块中,发送信息模块的实现过程有下面几个步骤:(1)通过列表双击一个好友为聊天对象,弹出聊天窗口;(2)用户按下发送按钮后,检测对方是否在线,检测对方是否在线(3)将聊天内容发送出去(4)在本地即时聊天内容显示的编辑框中添加发送的内容并写入聊天记录。
B、接收信息模块聊天模块中,接收信息模块的实现过程有下面几个步骤:(1)由主界面判断接收到信息的类型,是否为好友发来信息,如果是,则打开聊天窗口(2)读取消息,并写入聊天记录,(3)载入字体颜色信息。
(4) 显示聊天记录C、聊天记录管理模块聊天记录管理模块的实现过程有下面几个步骤:(1)将发送内容和接收内容写入文本文件;(2)显示聊天记录;(3)删除聊天记录。
D、字体颜色模块实现字体颜色模块的过程有下面几个步骤:(1)调用系统字体,获取字体,写入存档(2) 调用系统字体颜色,获取颜色,写入存档(3)读取、更新字体颜色。
第一章系统分析1.1 系统设计要求:1.2.3.1.2 系统原理框图本次课程设计的原理框图如图1.1所示:图1.1系统原理框图1.3 系统设计原理局域网聊天程序的实现主要为局域网内的计算机提供交流的平台。
完成一个基于服务器和客户端的局域网通讯软件,类似于聊天室,可进行注册、登录、系统信息记录、聊天等功能。
用户容易使用,便于管理。
第二章系统设计理论基础2.1 TCP/IP协议TCP/IP协议的核心部分是传输层协议(TCP、UDP),网络层协议(IP)和物理接口层,这三层通常是在操作系统内核中设计。
因此用户一般不涉及。
TCP是面向连接的,通信双方保持一条通路,好比目前的电话线,使用telnet登陆BBS,用的就是TCP协议;UDP 是无连接的,通信双方都不保持对方的状态,浏览器访问Internet时使用的HTTP协议就是基于UDP协议的。
编程时,编程界面有两种形式:一、是由内核心直接提供的系统调用;二、使用以库函数方式提供的各种函数。
前者为核内设计,后者为核外设计。
用户服务要通过核外的应用程序才能设计,所以要使用套接字(socket)来设计。
2.2 客户机/服务器模式C/S结构(Client/Server结构)是大家熟知的客户机和服务器结构。
它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销。
目前大多数应用软件系统都是Client/Server形式的两层结构,由于现在的软件应用系统正在向分布式的Web应用发展,Web和Client/Server 应用都可以进行同样的业务处理,应用不同的模块共享逻辑组件;因此,内部的和外部的用户都可以访问新的和现有的应用系统,通过现有应用系统中的逻辑可以扩展出新的应用系统。
这也就是目前应用系统的发展方向。
首先服务器方要启动,并根据请求提供相应服务:(1)打开一通信通道并告知本地主机,它在某一公认地址端口上(如http为80)接受客户请求。
网络程序设计课程设计--vc(mfc)实现简单的聊天室程序网络程序设计课程设计--vc(mfc)实现简单的聊天室程序《网络程序设计》课程设计报告书题目:简单的聊天室程序专业:网络工程完成日期:一、题目:简单的聊天室程序要求:本题是一个简单的聊天室程序,采用客户/服务器模式,分为客户端程序和服务器端程序。
由于服务器只能支持一个客户,实际上是一个点对点通信的程序。
客户端程序和服务器程序通过网络交换聊天字符串内容,并在窗口的列表框中显示。
l 。
二、系统概要设计聊天室是分客户端和服务端两个应用程序的,两个应用程序要想实现交互必须编写相应的指令和识别指令的代码,我写的这是个指令依次是启动停止用户退出的命令,但用户想要进行以上动作中的任何一个时,在用户按下按键的时候,客户端都是向服务端发送相应的指令,再由服务端实际的执行。
三、系统详细设计对概要设计中提到的功能函数进行详细设计。
服务器端:// ChatRoomServerDlg.cpp : implementation file // #include “stdafx.h“ #include “ChatRoomServer.h“ #include “ChatRoomServerDlg.h“ #include “ListenSocket.h“ #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerDlg dialog CChatRoomServerDlg::CChatRoomServerDlg(CWnd* pParent /*=NULL*/) : CDialog(CChatRoomServerDlg::IDD, pParent) { //{{AFX_DATA_INIT(CChatRoomServerDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CChatRoomServerDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CChatRoomServerDlg)DDX_Control(pDX, IDC_BUTTON_STOP, m_IDC_BUTTON_STOP); DDX_Control(pDX, IDC_BUTTON_START, m_IDC_BUTTON_START); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CChatRoomServerDlg, CDialog) //{{AFX_MSG_MAP(CChatRoomServerDlg)ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart) ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerDlg message handlers BOOL CChatRoomServerDlg::OnInitDialog(){ CDialog::OnInitDialog(); // Add “About.“ menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX ASSERT(IDM_ABOUTBOX AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application s main window is not a dialog SetIcon(m_hIcon, TRUE);// Set big icon SetIcon(m_hIcon, FALSE);// Set small icon // TODO: Add extra initialization here m_IDC_BUTTON_STOP.EnableWindow(FALSE); return TRUE; // return TRUE unless you set the focus to a control } void CChatRoomServerDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below //to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CChatRoomServerDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect( int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CChatRoomServerDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CChatRoomServerDlg::OnButtonStart() { // TODO: Add your control notification handler code here m_IDC_BUTTON_START.EnableWindow(FALSE);//使启动按钮无效ListenSocket.Create(6767);//创建监听套接字端口为6767 ListenSocket.Listen();//开始监听m_IDC_BUTTON_STOP.EnableWindow(TRUE);//将停止按钮激活} void CChatRoomServerDlg::OnButtonStop() { // TODO:Add your control notification handler code here m_IDC_BUTTON_STOP.EnableWindow(FALSE);//使停止按钮无效ListenSocket.Close();//关闭监听套接字m_IDC_BUTTON_START.EnableWindow(TRUE);//将启动按钮激活} // ChatRoomServer.h : main header file for the CHATROOMSERVER application // #if !defined(AFX_CHATROOMSERVER_H__680EC642_E19 B_4D55_88DF_2C9E9B1B30FD__INCLUDED_) #define AFX_CHATROOMSERVER_H__680EC642_E19B_4D55_88 DF_2C9E9B1B30FD__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #ifndef __AFXWIN_H__ #error include stdafx.h before including this file for PCH #endif #include “resource.h“// main symbols ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerApp: // See ChatRoomServer.cpp for the implementation of this class // class CChatRoomServerApp : public CWinApp { public: CChatRoomServerApp(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CChatRoomServerApp) public: virtual BOOL InitInstance(); //}}AFX_VIRTUAL // Implementation //{{AFX_MSG(CChatRoomServerApp) // NOTE - the ClassWizard will add and remove member functions here. // DONOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_CHATROOMSERVER_H__680EC642_E19B _4D55_88DF_2C9E9B1B30FD__INCLUDED_) // ChatRoomServerDlg.h : header file // #if !defined(AFX_CHATROOMSERVERDLG_H__5BE648B6 _8A9C_4E90_BF1D_20FE943A525F__INCLUDED_) #define AFX_CHATROOMSERVERDLG_H__5BE648B6_8A9C_4E9 0_BF1D_20FE943A525F__INCLUDED_ #include “ClientSocketList.h“// Added by ClassView #include “ListenSocket.h“// Added by ClassView #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerDlg dialog class CChatRoomServerDlg : public CDialog { // Construction public: CListenSocket ListenSocket; CChatRoomServerDlg(CWnd* pParent = NULL);// standard constructor // Dialog Data //{{AFX_DATA(CChatRoomServerDlg) enum { IDD =IDD_CHATROOMSERVER_DIALOG }; CButtonm_IDC_BUTTON_STOP;CButtonm_IDC_BUTTON_START; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CChatRoomServerDlg) protected: virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CChatRoomServerDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnButtonStart(); afx_msg void OnButtonStop(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_CHATROOMSERVERDLG_H__5BE648B6_ 8A9C_4E90_BF1D_20FE943A525F__INCLUDED_)#if !defined(AFX_CLIENTSOCKET_H__5B707F31_3AD5_4F 47_B58E_ECFC99EB60F0__INCLUDED_) #define AFX_CLIENTSOCKET_H__5B707F31_3AD5_4F47_B58E_ECFC99EB60F0__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // ClientSocket.h : header file // ///////////////////////////////////////////////////////////////////////////// // CClientSocket command target class CClientSocketList; class CClientSocket : public CSocket { // Attributes public: // Operations public: CClientSocket(CClientSocketList *); virtual ~CClientSocket(); // Overrides public: CClientSocketList *List; CClientSocket * Front; CClientSocket * Next; // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CClientSocket) public: virtual void OnReceive(int nErrorCode); virtual void OnClose(int nErrorCode); //}}AFX_VIRTUAL // Generated message map functions //{{AFX_MSG(CClientSocket) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG // Implementation protected: }; ///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_CLIENTSOCKET_H__5B707F31_3AD5_4F4 7_B58E_ECFC99EB60F0__INCLUDED_) //ClientSocketList.h: interface for the CClientSocketList class. // //////////////////////////////////////////////////////////////////////#if !defined(AFX_CLIENTSOCKETLIST_H__E746355D_FA1 0_4D12_B544_2FF152C16414__INCLUDED_) #define AFX_CLIENTSOCKETLIST_H__E746355D_FA10_4D12_B5 44_2FF152C16414__INCLUDED_ #include “ClientSocket.h“ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CClientSocketList { public: BOOL Sends(CClientSocket *); BOOL Add(CClientSocket *); CClientSocket * Head; CClientSocketList(); virtual ~CClientSocketList(); }; #endif // !defined(AFX_CLIENTSOCKETLIST_H__E746355D_FA10 _4D12_B544_2FF152C16414__INCLUDED_)#if !defined(AFX_LISTENSOCKET_H__5D655304_370E_468 0_A556_E417552D24EC__INCLUDED_) #define AFX_LISTENSOCKET_H__5D655304_370E_4680_A556_E4 17552D24EC__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // ListenSocket.h : header file // #include “ClientSocketList.h“ ////////////////////////////////////////////////////////////// /////////////// // CListenSocket command target class CListenSocket : public CSocket { // Attributes public: //Operations public: CClientSocketList CCSL;//客户socket列表CListenSocket(); virtual ~CListenSocket(); // Overrides public: // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CListenSocket) public: virtual void OnAccept(int nErrorCode);//重载OnAccept函数//}}AFX_VIRTUAL // Generated message map functions //{{AFX_MSG(CListenSocket) // NOTE - the ClassWizard will add and remove member functions here. //}}AFX_MSG // Implementation protected: }; ///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_LISTENSOCKET_H__5D655304_370E_4680 _A556_E417552D24EC__INCLUDED_) // ChatRoomServer.cpp : Defines the class behaviors for the application. // #include “stdafx.h“ #include “ChatRoomServer.h“ #include “ChatRoomServerDlg.h” #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerAppBEGIN_MESSAGE_MAP(CChatRoomServerApp, CWinApp) //{{AFX_MSG_MAP(CChatRoomServerApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerApp construction CChatRoomServerApp::CChatRoomServerApp() { // TODO: add construction code here, // Place all significant initialization in InitInstance } ///////////////////////////////////////////////////////////////////////////// // The one and only CChatRoomServerApp object CChatRoomServerApp theApp; ///////////////////////////////////////////////////////////////////////////// // CChatRoomServerApp initialization BOOL CChatRoomServerApp::InitInstance() { if (!AfxSocketInit()) { AfxMessageBox(IDP_SOCKETS_INIT_FAILED); return FALSE; } AfxEnableControlContainer(); // Standard initialization // If you are not using these features and wish to reduce the size // of your final executable, you should remove from the following // the specific initialization routines you do not need. #ifdef _AFXDLL Enable3dControls();// Call thiswhen using MFC in a shared DLL #else Enable3dControlsStatic();// Call this when linking to MFC statically #endif CChatRoomServerDlg dlg; m_pMainWnd = int nResponse = dlg.DoModal(); if (nResponse == IDOK) { // TODO: Place code here to handle when the dialog is // dismissed with OK } else if (nResponse == IDCANCEL) { // TODO: Place code here to handle when the dialog is // dismissed with Cancel } // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application s message pump. return FALSE; } II 客户端:客户端:// ChatRoomClient.cpp : Defines the class behaviors for the application. // #include “stdafx.h“ #include “ChatRoomClient.h“ #include “ChatRoomClientDlg.h“ #include “ConnectedDlg.h“ #include “ClientSocket.h“ #ifdef _DEBUG #d efine new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif CClientSocket curSocket; ///////////////////////////////////////////////////////////////////////////// // CChatRoomClientAppBEGIN_MESSAGE_MAP(CChatRoomClientApp, CWinApp) //{{AFX_MSG_MAP(CChatRoomClientApp) // NOTE - theClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChatRoomClientApp construction CChatRoomClientApp::CChatRoomClientApp。
MFC聊天系统的制作流程孙鑫的多线程与聊天室程序的创建,照样子自己也写了个多线程的聊天程序。
以免以后忘了,在此小总结一下下:1.利用MFC对话框建立聊天程序的界面:如下最上面是一个接受数据的编辑框,下面分别是一个Ip地址控件和发送数据的编辑框,左下角是触发发送数据的按钮。
2.加载套接字库,在MFC中用AfxSocketInit()加载套接字库。
需要注意的是这个函数要在程序的初始化函数中调用,即在Appliacation的InitInstance()中调用AfxSocketInit();3.初始化套接字。
在对话框中添加一个成员函数SockInit(),用来初始化套接字,然后在对话框初始化函数OnInitDlg()中调用SockInit()。
Tip:因为聊天程序既包含接收端又包含发送端,所以需要绑定Ip和端口。
4.创建多线程。
接受数据时,如没有数据到来,则会阻塞,导致程序暂停运行,所以把接受数据工作放到单独的线程中。
在OnInitDlg()中创建多线程。
Tip:因为需要给线程传递一个通信的套接字和响应消息的窗口句柄,所以需要额外定义一个结构体,用来存储这两个参数。
struct RECVPARAM{HWND hWnd; //接收数据窗体的句柄SOCKET sock; //接收数据的套接字};5.实现线程过程函数。
Tip:如果要求不能用全局函数的话,那线程过程函数就要定义为static(它属于类本身).在线程过程函数中循环接受消息,利用::PostMessgae()函数给接受数据编辑框发送消息,以实现显示信息的功能6.自定义消息的实现。
因为在PostMessage中是自定义的消息(WM_RECVDATA),所以需要完成消息映射。
(1)定义消息值#define WM_RECVDATA WM_USER+1 (2)声明消息处理函数:afx_msg void OnRecvData(WPARAM wParam,LPARAM lParam);(3)完成消息映射:ON_MESSAGE(WM_RECVDATA,OnRecvData)7.实现OnRecvData()函数。
本系统基于客户端/服务器基本原理,程序即是服务端,也是客户端,通过IP就可以相互添加好友,并且实现点到点通信,有聊天记录(未实现根据用户发送的消息而改变字体颜色,只能在客户端改),字体颜色设置(一改全改~),包含主界面MaindBord和聊天Talk两大功能模块。
(1) MaindBord模块A、登录模块登陆模块的实现过程有下面几个步骤:(1)初始化列表信息,获取用户名,服务器的IP地址,使按键失效(2)确认登陆后创建套接字,绑定,监听(3)初始化成功后,激活添加好友和隐藏功能B、好友模块添加好友的实现过程有下面几个步骤:(1)弹出对话框(2)获取对话框中的IP(3)检查对方是否在线,建立连接(4)发送请求验证C、好友列表模块(1)客户接收请求,将服务端加入列表,发送客户端信息(2)服务端得到客户端信息,加入列表(3)双击好友列表,弹出发送信息对话框D、隐藏模块(1)隐藏与显示(2)响应鼠标,弹出控制菜单(2)聊天Talk模块A、发送信息模块聊天模块中,发送信息模块的实现过程有下面几个步骤:(1)通过列表双击一个好友为聊天对象,弹出聊天窗口;(2)用户按下发送按钮后,检测对方是否在线,检测对方是否在线(3)将聊天内容发送出去(4)在本地即时聊天内容显示的编辑框中添加发送的内容并写入聊天记录。
B、接收信息模块聊天模块中,接收信息模块的实现过程有下面几个步骤:(1)由主界面判断接收到信息的类型,是否为好友发来信息,如果是,则打开聊天窗口(2)读取消息,并写入聊天记录,(3)载入字体颜色信息。
(4) 显示聊天记录C、聊天记录管理模块聊天记录管理模块的实现过程有下面几个步骤:(1)将发送内容和接收内容写入文本文件;(2)显示聊天记录;(3)删除聊天记录。
D、字体颜色模块实现字体颜色模块的过程有下面几个步骤:(1)调用系统字体,获取字体,写入存档(2) 调用系统字体颜色,获取颜色,写入存档(3)读取、更新字体颜色。
基于MFC的即时通讯软件的设计与实现详细设计修改履历目录1文档概述 (4)1.1文档目的和范围 (4)1.2术语/缩略语 (4)1.3参考文档 (4)2处理 (4)2.1模块数据结构定义 (4)2.1.1全局变量定义 (4)2.2模块功能实现 (5)2.2.1模块共有函数部分 (5)2.2.2服务器模块内部函数 (13)2.2.3客户端模块内部函数 (17)1文档概述1.1 文档目的和范围该项目主要完成的是Windows下基于MFC的聊天软件,主要包括客户端模块和服务器模块,本文档的主要内容是本项目的各个模块详细设计,包括相应的模块结构,函数声明,宏定义等,主要目的是为项目的编码阶段提供设计参考。
1.2 术语/缩略语1.3 参考文档2处理2.1 模块数据结构定义2.1.1全局变量定义1.宏定义const int MSG_LOGOIN = 0x01; //登陆const int MSG_SEND = 0x11; //发送消息const int MSG_CLOSE = 0x02; //退出const int MSG_UPDATE = 0x21; //更新信息2.数据结构定义typedef struct tagHeader{int type ; //协议类型int nContentLen; //将要发送的内容的长度char to_user[20];char from_user[20];}HEADER ,*LPHEADER;2.2 模块功能实现2.2.1模块共有函数部分2.2.1.1 msg_process【函数式样】【函数处理流程】2.2.1.2 send_msg 【函数式样】【函数处理流程】2.2.1.3 draw_arc_windown 【函数式样】【函数处理流程】2.2.1.4 get_local_ip 【函数式样】【函数处理流程】2.2.1.5 receive_msg 【函数式样】【函数处理流程】2.2.1.6 user_*系列函数【函数式样】【函数处理流程】2.2.2服务器模块内部函数2.2.2.1 OnLogoIn() 【函数式样】【函数处理流程】2.2.2.2 OnMSGTranslate【函数处理流程】2.2.2.3 UpdateAllUser2.2.2.4 UpdateServerLog2.2.2.5 OnAccept2.2.2.6 OnReceive2.2.2.72.2.3客户端模块内部函数2.2.3.1 OnBnClickedBtnLogoin2.2.3.2 LogoIn2.2.3.3 OnBnClickedBtnSend【函数处理流程】2.2.3.4 UpdateUserInfo【函数处理流程】2.2.3.5 WChar2MByte。
操作系统实验报告一 概要设计3.1 系统体系结构本系统由教注册、登陆和聊天等部分组成。
注册模块主要完成用户信息的提交,登陆模块用于验证操作者的信息,聊天模块主要包括群聊、私聊,刷新在线用户列表、显示其他用户发送的信息、发送信息给其他用户、上传下载资源等(未实现)。
系统体系结构如下图所示:未通过通过( 注册模块 )开始提交服务器审核提示用户已 被注册注册成功注册信息 完成未通过通过(登录模块 )判断完成登录 提示“用户名或密码错误”是否 私聊群聊 否是(聊天模块)选择是否开启音乐 开启音乐软件发送信息/接受信息 退出结束指定私聊对象是否退出 选择聊天方式3.2系统的设计与实现3.2.1数据库设计本系统主要采用以下数据库表:个人信息表个人信息表主要存储用户的一些基本注册信息,其中包括用户名和密码字段,主要用于用户系统对用户的识别。
具体内容见表1:表1 个人信息表字段类型及长度备注用户名varchar(50) 主键密码varchar(50) 不能为空真名varchar(50) 可为空年纪varchar(50) 可为空性别varchar(50) 可为空职业varchar(50) 可为空3.2.2模块实现3.2.2.1注册模块的实现✧注册用户首次使用该系统应该先完成注册。
按照系统提示的步骤,逐步完成注册后即可登录该系统,使用该系统。
3.2.2.2登陆模块的实现✧登录用户凭借已经注册的用户名和密码登陆该系统。
3.2.2.3聊天模块的实现✧群聊\ 私聊用户点击界面上的群聊或私聊按钮即可和他人进行聊天。
✧听音乐用户点击听音乐的按钮,可打开音乐软件进行听音乐。
✧刷新在线用户列表和显示别人发来的信息当有人登陆是可以自动刷新登陆列表,当有人发送信息时,会显示信息。
✧上传下载(暂未实现)用户可以点击上传或下载按钮,把电脑资源上传或从服务器下载资源,而且用户可点击修改按钮,实现上传信息的修改。
二详细设计4.1用户进行通信用户按照界面提示进行交流,通过MFC的SOCKET编程实现客户端与服务器的数据传输,下面通过流程图和主要代码段详细说明设计过程:(通信流程图)因此只要安装了客户端,连接了客户端后即可与其他人进行通信。
聊天程序设计报告
----网络编程设计报告
目录
【1】设计原理————————————————————————1【2】功能描述————————————————————————1【3】详细设计————————————————————————2【4】工作进度————————————————————————7【5】设计总结————————————————————————8【6】使用方法————————————————————————9【7】附录——————————————————————————9
一. 设计原理
计算机网络技术发展至今已经大大超越了人们当初的预想,无论是人们日常的工作还是学习,我们都越来越多的依靠到互联网。
各种实时性的聊天娱乐软件也同时诞生,而且为我们的即时通讯带来了众多的方便,比如说大家所熟知的腾讯QQ、微软的MSN、中国移动的Fetion等,都是做的比较成功的实时聊天工具。
随着网络的日益普及,各种聊天工具也层出不穷,但当我们学习了《网络编程》这门课程之后,我们便会觉得,其实要实现简单的网络通讯其实并不难。
接下来的课程设计就是针对一个简单的网络聊天程序,利用MFC为开发工具,实现基本的通讯功能。
此程序主要分为两个模块:服务线程和聊天线程。
服务线程用于提供一个网络端口,等待客户线程发出请求,登录到作为服务端的程序,然后进行网络通讯和消息的收发;客户端可通过服务器端的IP地址发送连接请求,然后建立连接,进行通讯。
整个程序的主体使用了CSocket类的方法,实现了网络通讯聊天。
二.功能描述(需求分析)
1、一对一会话。
此程序既可以作为服务器,也可以作为客户端。
当发起聊
天请求时是客户端,而当接受连接请求时时服务器。
通讯基于可靠的TCP连接。
2、修改联系人通讯地址。
可以根据联系人IP地址和端口的不同建立不同的连接。
可以实时修改联系人的地址。
3、多线程技术。
进程启动时会开启一个专门用于监听连接请求的服务进程,线程函数为UINT threadListen(LPVOID lpParam),用来被动接受聊天请求。
无论是主动发起聊天请求还是被动接受连接请求,都将启动一个名为CIMTalking 的线程,专门处理聊天业务。
4、整个程序的主体使用了基于CSocket类的网络编程方法,综合运用了CSocket、CSocketFile、CArchive等类的方法,实现了网络通讯聊天。
IM的功能可划分为以下几点:
1)界面显示:将在线好友显示在好友列表中,并实现好友分组,便于选择联系人。
2)聊天功能:与好友聊天。
3)聊天纪录:能保存聊天纪录,并能察看聊天纪录。
(未实现)
4)信息提示:当连接失败(一般为对方不在线)时,提醒用户连接失败及原因。
5)修改联系地址:由于本聊天程序不涉及登录服务器,故开启进程即为在线,否则离线。
故需要动态修改联系人IP地址及端口号。
聊天程序模块图
三、详细设计
程序中主要变量及类的功能说明如下:
CIMTalkingDlg --- 聊天过程处理函数类
CIMTalking ---- 用于处理聊天过程的运行时类
peerAddress ---- 联系人地址,包括套接字地址和联系人姓名,这是一个结构体
CIMApp ----- 程序主线程
CIMDlg ----- 程序UI线程,用于处理消息,界面窗口初始化等工作CChatSock ---- 专门用于聊天的套接字类,继承自CSocket
CAddrDlg ----- 显示联系人地址、修改联系人地址
CAboutDlg----- 显示程序版本信息
联系人地址结构体类型:
struct peerAddress
{
struct sockaddr_in peerAddr; //对方地址
char peerName[20]; //对方姓名
};
类图框架
用Visual Studio 2008逆向工程导出的详细类图
程序流程图
UI设计
程序主界面
聊天对话框界面
修改联系人地址对话框界面四.工程进度
第一阶段 6月4号-----6月10号分析功能要求
五、设计总结
4.1 程序的应改进之处:
1、无法知道联系人是否在线,除非连接;而且若把联系人的套接字地址,即IP 地址和端口搞错,通讯失败。
即使对方在线,也有可能出错;这是本程序最大的缺憾。
2、被连接时自动启动窗口,表示对方已经发起聊天请求,可以改为发送第一条消息后自动弹出聊天窗口。
3、聊天记录文件应该加密,虽然在本程序中没有实现。
4、可以在程序启动后立即探测联系人的状态,并在用户界面上显示其状态,即是否在线。
4.2 个人小结
1、在做这次网络创新实验之前基本上还没接触过MFC套接字网络编程,这次实验是在边学习边实践的基础上完成的。
由于临近考试,因此做的时间不多,做的结果不太好,与自己原来的设想还有点差距。
2、通过“计算机网络基础”自己对网络的基础知识也打下了很好的基础。
这次网络实验可以说是在理解网络的基础上对Windows Socket 编程的一次学习过程,虽然做的不好,但也学到了很多知识,对自己以后进行网络开发有很大的帮助。
3、在做本次实验时,我尽可能的将上一学期学的软件工程思想运用到这次开发实验中来。
在进行详细设计之前,先进行需求功能分析,在功能分析的基础上,划分程序的框架,创建类来分担不同的功能,并根据类的功能加入函数和变量,这对详细设计有一个总纲的作用。
4、在开始这个设计之前,对MFC编程(大一开设的半学期课程)只是初步了解,没有掌握MFC编程的原理。
通过本次设计,对MFC的机制乃至Windows程序的运行机制加深了了解,同时基本掌握了MFC编程方法,这是本次设计最大的收获之一!
5、一些东西貌似很简单,但在实现时往往遇到意想不到的困难。
比如本次设计中,由于缺乏编程经验,加入如何开启一个新的线程,与控制台程序就有很大不
同,虽然思想相同;再比如一些控件的使用方法,比如右击一个树形控件子项目,如何获取其text,就是一个问题,费了很大力气才发现少了如下语句:ScreenToClient(&myPoint);//该函数把屏幕上指定点的屏幕坐标转换成用户坐标
然后再执行
m_hTreeItem = (myPoint, &uFlags);//获取选取的项目的控件句柄
6、第一次在本次设计中用到了C++关键字 extern ;第一次在MFC程序中用到了全局变量;第一次在程序中使用MFC多线程函数AfxBeginThread();第一次试用了CTreeCtrl等控件;第一次实现了CSocket、CSocketFile、CArchive类的联合使用以实现消息的发送和接收;对MFC套接字实现消息收发的原理有了较深的了解。
总结:动手是提高的最佳手段!虽然过程中会遇到很多令人沮丧的问题,但解决这些问题之后是一种强烈的成就感!
六、使用方法
要进行通信,需要编译两个不同程序,但只要交换void
CIMDlg::OnDblclkFriend(NMHDR* pNMHDR, LRESULT* pResult)和
UINT threadListen(LPVOID lpParam)函数中的端口号即可,编译生成可执行文件后即可通过双击好友名单收发消息。
七、附录
程序代码见附件。