用VC 简单的多线程聊天室程序完整课程设计

合集下载

网络程序设计课程设计--VC(MFC)实现简单的聊天室程序

网络程序设计课程设计--VC(MFC)实现简单的聊天室程序

《网络程序设计》课程设计报告书题目:简单的聊天室程序专业:网络工程完成日期:一、题目:简单的聊天室程序要求:本题是一个简单的聊天室程序,采用客户/服务器模式,分为客户端程序和服务器端程序。

由于服务器只能支持一个客户,实际上是一个点对点通信的程序。

客户端程序和服务器程序通过网络交换聊天字符串内容,并在窗口的列表框中显示。

二、系统概要设计聊天室是分客户端和服务端两个应用程序的,两个应用程序要想实现交互必须编写相应的指令和识别指令的代码,我写的这是个指令依次是启动停止用户退出的命令,但用户想要进行以上动作中的任何一个时,在用户按下按键的时候,客户端都是向服务端发送相应的指令,再由服务端实际的执行。

三、系统详细设计对概要设计中提到的功能函数进行详细设计。

服务器端:// ChatRoomServerDlg.cpp : implementation file//#include "stdafx.h"#include "ChatRoomServer.h"#include "ChatRoomServerDlg.h"#include "ListenSocket.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CAboutDlg dialog used for App Aboutclass 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// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_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_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CChatRoomServerDlg dialogCChatRoomServerDlg::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_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CChatRoomServerDlg message handlersBOOL CChatRoomServerDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->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 dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization herem_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 & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;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 paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint 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;// Draw the icondc.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 herem_IDC_BUTTON_START.EnableWindow(FALSE);//使启动按钮无效ListenSocket.Create(6767);//创建监听套接字端口为6767ListenSocket.Listen();//开始监听m_IDC_BUTTON_STOP.EnableWindow(TRUE);//将停止按钮激活}void CChatRoomServerDlg::OnButtonStop(){// TODO: Add your control notification handler code herem_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_CHA TROOMSERVER_H__680EC642_E19B_4D55_88DF_2C9E9B1B30FD __INCLUDED_)#defineAFX_CHATROOMSERVER_H__680EC642_E19B_4D55_88DF_2C9E9B1B30FD__INCLUDE D_#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.// DO NOT EDIT what you see in these blocks of generated code !//}}AFX_MSGDECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCA TION}}// 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_CHA TROOMSERVERDLG_H__5BE648B6_8A9C_4E90_BF1D_20FE943A5 25F__INCLUDED_)#defineAFX_CHATROOMSERVERDLG_H__5BE648B6_8A9C_4E90_BF1D_20FE943A525F__INCL UDED_#include "ClientSocketList.h" // Added by ClassView#include "ListenSocket.h" // Added by ClassView#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000/////////////////////////////////////////////////////////////////////////////// CChatRoomServerDlg dialogclass CChatRoomServerDlg : public CDialog{// Constructionpublic:CListenSocket ListenSocket;CChatRoomServerDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data//{{AFX_DATA(CChatRoomServerDlg)enum { IDD = IDD_CHATROOMSERVER_DIALOG };CButton m_IDC_BUTTON_STOP;CButton m_IDC_BUTTON_START;//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CChatRoomServerDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected: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_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCA TION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif// !defined(AFX_CHA TROOMSERVERDLG_H__5BE648B6_8A9C_4E90_BF1D_20FE943A52 5F__INCLUDED_)#if !defined(AFX_CLIENTSOCKET_H__5B707F31_3AD5_4F47_B58E_ECFC99EB60F0__IN CLUDED_)#defineAFX_CLIENTSOCKET_H__5B707F31_3AD5_4F47_B58E_ECFC99EB60F0__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// ClientSocket.h : header file///////////////////////////////////////////////////////////////////////////////// CClientSocket command targetclass CClientSocketList;class CClientSocket : public CSocket{// Attributespublic:// Operationspublic:CClientSocket(CClientSocketList *);virtual ~CClientSocket();// Overridespublic: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// Implementationprotected:};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCA TION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif// !defined(AFX_CLIENTSOCKET_H__5B707F31_3AD5_4F47_B58E_ECFC99EB60F0__INC LUDED_)// ClientSocketList.h: interface for the CClientSocketList class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_CLIENTSOCKETLIST_H__E746355D_FA10_4D12_B544_2FF152C16414__ INCLUDED_)#defineAFX_CLIENTSOCKETLIST_H__E746355D_FA10_4D12_B544_2FF152C16414__INCLUDE D_#include "ClientSocket.h"#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000class CClientSocketList{public:BOOL Sends(CClientSocket *);BOOL Add(CClientSocket *);CClientSocket * Head;CClientSocketList();virtual ~CClientSocketList();};#endif// !defined(AFX_CLIENTSOCKETLIST_H__E746355D_FA10_4D12_B544_2FF152C16414__I NCLUDED_)#if !defined(AFX_LISTENSOCKET_H__5D655304_370E_4680_A556_E417552D24EC__INC LUDED_)#defineAFX_LISTENSOCKET_H__5D655304_370E_4680_A556_E417552D24EC__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000// ListenSocket.h : header file//#include "ClientSocketList.h"/////////////////////////////////////////////////////////////////////////////// CListenSocket command targetclass CListenSocket : public CSocket{// Attributespublic:// Operationspublic:CClientSocketList CCSL;//客户socket列表CListenSocket();virtual ~CListenSocket();// Overridespublic:// 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// Implementationprotected:};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCA TION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif// !defined(AFX_LISTENSOCKET_H__5D655304_370E_4680_A556_E417552D24EC__INCL UDED_)// 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_FILEstatic 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_MSGON_COMMAND(ID_HELP, CWinApp::OnHelp)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CChatRoomServerApp constructionCChatRoomServerApp::CChatRoomServerApp(){// TODO: add construction code here,// Place all significant initialization in InitInstance}/////////////////////////////////////////////////////////////////////////////// The one and only CChatRoomServerApp objectCChatRoomServerApp theApp;/////////////////////////////////////////////////////////////////////////////// CChatRoomServerApp initializationBOOL 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 _AFXDLLEnable3dControls(); // Call this when using MFC in a shared DLL #elseEnable3dControlsStatic(); // Call this when linking to MFC statically#endifCChatRoomServerDlg dlg;m_pMainWnd = &dlg;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#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCClientSocket curSocket;/////////////////////////////////////////////////////////////////////////////// CChatRoomClientAppBEGIN_MESSAGE_MAP(CChatRoomClientApp, CWinApp)//{{AFX_MSG_MAP(CChatRoomClientApp)// NOTE - the ClassWizard will add and remove mapping macros here.// DO NOT EDIT what you see in these blocks of generated code!//}}AFX_MSGON_COMMAND(ID_HELP, CWinApp::OnHelp)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CChatRoomClientApp constructionCChatRoomClientApp::CChatRoomClientApp(){// TODO: add construction code here,// Place all significant initialization in InitInstance}/////////////////////////////////////////////////////////////////////////////// The one and only CChatRoomClientApp objectCChatRoomClientApp theApp;/////////////////////////////////////////////////////////////////////////////// CChatRoomClientApp initializationBOOL CChatRoomClientApp::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 _AFXDLLEnable3dControls(); // Call this when using MFC in a shared DLL #elseEnable3dControlsStatic(); // Call this when linking to MFC statically#endifCConnectedDlg cdlg(&curSocket);if (cdlg.DoModal()==IDCANCEL) return FALSE;CChatRoomClientDlg dlg(&curSocket);m_pMainWnd = &dlg;curSocket.SetDlg(&dlg);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;}// ChatRoomClientDlg.cpp : implementation file//#include "stdafx.h"#include "ChatRoomClient.h"#include "ChatRoomClientDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CAboutDlg dialog used for App Aboutclass 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// Implementationprotected://{{AFX_MSG(CAboutDlg)//}}AFX_MSGDECLARE_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_MAPBEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CChatRoomClientDlg dialogCChatRoomClientDlg::CChatRoomClientDlg(CClientSocket *tmp,CWnd* pParent /*=NULL*/) : CDialog(CChatRoomClientDlg::IDD, pParent){//{{AFX_DATA_INIT(CChatRoomClientDlg)m_IDC_EDIT_MESSAGE = _T("");//}}AFX_DATA_INIT// Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);myServerSocket=tmp;}void CChatRoomClientDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CChatRoomClientDlg)DDX_Control(pDX, IDC_STATIC_NIKENAME, m_STATIC_NIKENAME_CONTROL);DDX_Control(pDX, IDC_LIST_CHA TBOX, m_IDC_LIST_CHATBOX_CONTROL);DDX_Text(pDX, IDC_EDIT_MESSAGE, m_IDC_EDIT_MESSAGE);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CChatRoomClientDlg, CDialog)//{{AFX_MSG_MAP(CChatRoomClientDlg)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_BUTTON_SEND, OnButtonSend)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CChatRoomClientDlg message handlersBOOL CChatRoomClientDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu.// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->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 dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small iconm_STATIC_NIKENAME_CONTROL.SetWindowText(myServerSocket->NikeName);// TODO: Add extra initialization herereturn TRUE; // return TRUE unless you set the focus to a control}void CChatRoomClientDlg::OnSysCommand(UINT nID, LPARAM lParam){if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;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 CChatRoomClientDlg::OnPaint(){if (IsIconic()){CPaintDC dc(this); // device context for paintingSendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);// Center icon in client rectangleint 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;// Draw the icondc.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 CChatRoomClientDlg::OnQueryDragIcon(){return (HCURSOR) m_hIcon;}BOOL CChatRoomClientDlg::GetMessage(){char buff[1000];int count;count=myServerSocket->Receive(buff,1000);buff[count]=0;m_IDC_LIST_CHA TBOX_CONTROL.AddString(buff);return true;void CChatRoomClientDlg::OnButtonSend(){// TODO: Add your control notification handler code hereint n;char message[1000];UpdateData(TRUE);m_IDC_EDIT_MESSAGE=myServerSocket->NikeName+": "+m_IDC_EDIT_MESSAGE;n=m_IDC_EDIT_MESSAGE.GetLength();//message=new char(n+1);sprintf(message,"%s",m_IDC_EDIT_MESSAGE.GetBuffer(n));message[n]=0;if (myServerSocket->Send(message,n+1)){m_IDC_EDIT_MESSAGE="";UpdateData(FALSE);}else{AfxMessageBox("网络传输错误!!!");}}// ClientSocket.cpp : implementation file//#include "stdafx.h"#include "ChatRoomClient.h"#include "ClientSocket.h"#include "ChatRoomClientDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CClientSocketCClientSocket::CClientSocket()NikeName="";myDlg=0;}CClientSocket::~CClientSocket(){}BOOL CClientSocket::SetDlg(CChatRoomClientDlg *tmp){myDlg=tmp;return true;}// Do not edit the following lines, which are needed by ClassWizard.#if 0BEGIN_MESSAGE_MAP(CClientSocket, CSocket)//{{AFX_MSG_MAP(CClientSocket)//}}AFX_MSG_MAPEND_MESSAGE_MAP()#endif // 0/////////////////////////////////////////////////////////////////////////////// CClientSocket member functionsvoid CClientSocket::OnReceive(int nErrorCode){// TODO: Add your specialized code here and/or call the base class myDlg->GetMessage();CSocket::OnReceive(nErrorCode);}// ConnectedDlg1.cpp : implementation file//#include "stdafx.h"#include "ChatRoomClient.h"#include "ConnectedDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CConnectedDlg dialogCConnectedDlg::CConnectedDlg(CClientSocket * tmp,CWnd* pParent /*=NULL*/) : CDialog(CConnectedDlg::IDD, pParent){//{{AFX_DATA_INIT(CConnectedDlg)m_IDC_EDIT_ADDRESS = _T("");m_IDC_EDIT_NIKENAME = _T("");//}}AFX_DATA_INITmyServerSocket=tmp;}void CConnectedDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CConnectedDlg)DDX_Text(pDX, IDC_EDIT_ADDRESS, m_IDC_EDIT_ADDRESS);DDX_Text(pDX, IDC_EDIT_NIKENAME, m_IDC_EDIT_NIKENAME);//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CConnectedDlg, CDialog)//{{AFX_MSG_MAP(CConnectedDlg)//}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CConnectedDlg message handlersvoid CConnectedDlg::OnOK(){// TODO: Add extra validation hereUpdateData(TRUE);char *nikename,*address;int n;if (!myServerSocket->Create()){myServerSocket->Close();AfxMessageBox("网络创建错误!!");return;}n=m_IDC_EDIT_ADDRESS.GetLength();address=new char(n+1);sprintf(address,"%s",m_IDC_EDIT_ADDRESS.GetBuffer(n));address[n]=0;n=m_IDC_EDIT_NIKENAME.GetLength();nikename=new char(n+1);sprintf(nikename,"%s",m_IDC_EDIT_NIKENAME.GetBuffer(n));nikename[n]=0;if (!myServerSocket->Connect(address,6767)){myServerSocket->Close();AfxMessageBox("网络连接错误!请重新检查服务器地址的填写是否正确?");return;}myServerSocket->NikeName=nikename;CDialog::OnOK();}// stdafx.cpp : source file that includes just the standard includes// ChatRoomClient.pch will be the pre-compiled header// stdafx.obj will contain the pre-compiled type information#include "stdafx.h"// ChatRoomClient.h : main header file for the CHATROOMCLIENT application//#if !defined(AFX_CHATROOMCLIENT_H__4503F0DD_CA95_4F24_B6EE_3183B64B095B_ _INCLUDED_)#defineAFX_CHATROOMCLIENT_H__4503F0DD_CA95_4F24_B6EE_3183B64B095B__INCLUDE D_#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/////////////////////////////////////////////////////////////////////////////// CChatRoomClientApp:// See ChatRoomClient.cpp for the implementation of this class//class CChatRoomClientApp : public CWinApp{public:CChatRoomClientApp();// Overrides// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CChatRoomClientApp)public:virtual BOOL InitInstance();//}}AFX_VIRTUAL// Implementation//{{AFX_MSG(CChatRoomClientApp)// NOTE - the ClassWizard will add and remove member functions here.// DO NOT EDIT what you see in these blocks of generated code !//}}AFX_MSGDECLARE_MESSAGE_MAP()};///////////////////////////////////////////////////////////////////////////////{{AFX_INSERT_LOCA TION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif// !defined(AFX_CHATROOMCLIENT_H__4503F0DD_CA95_4F24_B6EE_3183B64B095B__I NCLUDED_)// ChatRoomClientDlg.h : header file//#if !defined(AFX_CHATROOMCLIENTDLG_H__4DF07865_B696_4641_82F8_4B32BF39595 9__INCLUDED_)#defineAFX_CHATROOMCLIENTDLG_H__4DF07865_B696_4641_82F8_4B32BF395959__INCLU DED_#include "ClientSocket.h" // Added by ClassView#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000//class ClientSocket;/////////////////////////////////////////////////////////////////////////////// CChatRoomClientDlg dialogclass CChatRoomClientDlg : public CDialog{// Constructionpublic:CClientSocket * myServerSocket;BOOL GetMessage();CChatRoomClientDlg(CClientSocket *,CWnd* pParent = NULL); // standard constructor// Dialog Data//{{AFX_DATA(CChatRoomClientDlg)enum { IDD = IDD_CHATROOMCLIENT_DIALOG };CStatic m_STATIC_NIKENAME_CONTROL;CListBox m_IDC_LIST_CHA TBOX_CONTROL;CString m_IDC_EDIT_MESSAGE;//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CChatRoomClientDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support//}}AFX_VIRTUAL// Implementationprotected:HICON m_hIcon;// Generated message map functions//{{AFX_MSG(CChatRoomClientDlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnButtonSend();//}}AFX_MSGDECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCA TION}}。

windows环境下C语言多线程实现网络编程多人聊天室

windows环境下C语言多线程实现网络编程多人聊天室

windows环境下C语言多线程实现网络编程多人聊天室在Windows环境下使用C语言实现多线程网络编程的多人聊天室是一个非常有趣和具有挑战性的项目。

在本文中,我将向您介绍如何使用C语言和Windows API来实现这样一个聊天室,并提供一些关键的代码示例。

首先,我们需要了解一些基本的网络编程概念。

在本例中,我们将使用TCP协议进行通信,因为它是一种可靠的协议,适用于需要确保数据传输完整性和顺序的场景。

要实现多人聊天室,我们需要一个服务器和多个客户端。

服务器将负责接收来自客户端的连接请求,并将消息广播给其他客户端。

客户端将负责连接到服务器,并发送和接收消息。

下面是一个简化的服务器代码示例:```c#include <stdio.h>#include <stdlib.h>#include <string.h>#include <winsock2.h>#define MAX_CLIENTS 10#define BUFFER_SIZE 1024DWORD WINAPI ClientHandler(LPVOID lpParam);int maiWSADATA wsaData;SOCKET serverSocket, clientSocket;struct sockaddr_in serverAddr, clientAddr;HANDLE threadHandles[MAX_CLIENTS];int clientCount = 0;// 初始化Winsockif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)printf("Failed to initialize winsock.\n");return 1;}//创建服务器套接字serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (serverSocket == INVALID_SOCKET)printf("Failed to create server socket.\n");return 1;}//设置服务器地址和端口serverAddr.sin_family = AF_INET;serverAddr.sin_addr.s_addr = INADDR_ANY;serverAddr.sin_port = htons(8888);//绑定服务器套接字到指定地址和端口if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)printf("Failed to bind server socket.\n");return 1;}//监听客户端连接请求if (listen(serverSocket, 5) == SOCKET_ERROR)printf("Failed to listen on server socket.\n");return 1;}printf("Server started. Waiting for connections...\n");while (1)//接受客户端连接请求int clientAddrSize = sizeof(clientAddr);clientSocket = accept(serverSocket, (structsockaddr*)&clientAddr, &clientAddrSize);if (clientSocket == INVALID_SOCKET)printf("Failed to accept client connection.\n");continue;}//创建线程处理客户端threadHandles[clientCount] = CreateThread(NULL, 0, ClientHandler, (LPVOID)clientSocket, 0, NULL);if (threadHandles[clientCount] == NULL)printf("Failed to create client handler thread.\n");closesocket(clientSocket);continue;}clientCount++;printf("Client connected. Total clients: %d\n", clientCount);}//关闭服务器套接字closesocket(serverSocket);// 清理WinsockWSACleanup(;return 0;DWORD WINAPI ClientHandler(LPVOID lpParam)SOCKET clientSocket = (SOCKET)lpParam;char buffer[BUFFER_SIZE];int bytesRead;while (1)//接收客户端消息bytesRead = recv(clientSocket, buffer, BUFFER_SIZE, 0);if (bytesRead <= 0)break;}//广播消息给其他客户端for (int i = 0; i < clientCount; i++)if (threadHandles[i] != NULL && threadHandles[i] != GetCurrentThread()send(threadHandles[i], buffer, bytesRead, 0);}}}//关闭客户端套接字closesocket(clientSocket);return 0;```上述代码包含一个主函数`main`和一个客户端处理函数`ClientHandler`。

c网络聊天室课程设计

c网络聊天室课程设计

c网络聊天室课程设计一、课程目标知识目标:1. 学生能够理解网络聊天室的基本概念,掌握网络通信的原理;2. 学生能够掌握网络聊天室的编程基础,了解相关的编程语言及库;3. 学生能够理解网络安全的重要性,了解网络聊天室的安全风险及防范措施。

技能目标:1. 学生能够运用所学知识,独立设计并实现一个简单的网络聊天室程序;2. 学生能够通过实际操作,掌握网络聊天室的搭建与调试技巧;3. 学生能够运用网络安全知识,提高网络聊天室的安全防护能力。

情感态度价值观目标:1. 培养学生对网络通信技术的好奇心与探究精神,激发学习兴趣;2. 培养学生团队合作意识,学会与他人共同解决问题;3. 增强学生的网络安全意识,树立正确的网络道德观念。

课程性质分析:本课程为信息技术课程,旨在让学生了解网络聊天室的相关知识,提高编程实践能力,同时注重培养学生的网络安全意识。

学生特点分析:本课程针对的是八年级学生,他们对新鲜事物充满好奇心,具备一定的信息技术基础,但编程实践能力和网络安全意识有待提高。

教学要求:1. 结合课本内容,注重理论与实践相结合,提高学生的编程实践能力;2. 重视学生的主体地位,鼓励学生积极参与课堂讨论与实践活动;3. 关注学生的个体差异,因材施教,提高学生的综合素质。

二、教学内容1. 网络聊天室基本概念与原理- 网络通信基础- 聊天室的组成与功能- 网络聊天室的分类2. 编程语言及库介绍- Python编程语言基础- Python网络编程库(如socket、asyncio等)- 常用网络聊天室开发框架3. 网络聊天室程序设计与实现- 客户端与服务器的通信原理- 消息传输协议(如TCP、UDP)- 网络聊天室程序设计步骤与实例4. 网络安全与道德规范- 网络聊天室的安全风险- 数据加密与身份认证- 网络道德观念与法律法规5. 教学大纲与进度安排- 第一周:网络聊天室基本概念与原理学习- 第二周:Python编程语言及网络编程库学习- 第三周:网络聊天室程序设计与实现- 第四周:网络安全与道德规范教育6. 教材章节与内容列举- 第八章:网络编程基础- 第九章:Python网络编程- 第十章:网络安全与道德规范教学内容确保科学性和系统性,结合课程目标,按照教学大纲安排和进度,使学生能够循序渐进地掌握网络聊天室的相关知识。

用VC++设计简单的聊天室程序完整课程设计

用VC++设计简单的聊天室程序完整课程设计

课程设计任务书学院专业用VC++设计简单的聊天室程序学生姓名:指导老师:摘要计算机网络技术发展至今已经大大超越了人们当初的预想,无论是人们日常的工作还是学习,我们都越来越多的依靠到互联网。

各种实时性的聊天娱乐软件也同时诞生,而且为我们的即时通讯带来了众多的方便,比如说大家所熟知的腾讯QQ、微软的MSN、移动的Fetion等,都是做的比较成功的实时聊天工具。

随着网络的日益普及,各种聊天工具也层出不穷,但当我们学习了《TCP/IP协议与网络编程》这门课程之后,我们便会觉得,其实要实现简单的网络通讯其实并不难。

接下来的课程设计就是针对一个简单的网络聊天程序,利用MFC为开发工具,实现基本的通讯功能。

在课程设计中,系统开发平台为Windows 2000,程序设计设计语言采用Visual C++,数据库采用MS SQL 2000,程序运行平台为Windows 98/2000/XP。

关键词聊天软件;网络通讯;MFC;课程设计;Visual C++1 引言1.1课题背景及意义当今世界正处于信息时代,计算机和通信网络是这一时代所谓“信息基础设施”。

在互联网相当普及的今天,在互联网上聊天对很多“网虫”来说已经是家常便饭了。

聊天室程序可以说是网上最简单的多点通信程序。

一个简单的聊天室, 从程序员的观点来看就是在多个I/O端点之间实现多对多的通信。

基于SOCKET的局域网通信是一种灵活的、易于实现的、低成本的方法。

它可以运行在各种使用TCP/IP协议作为通讯协议的网络上。

而在SOCKET API的帮助下,开发基于SOCKET的局域网通信软件也是易于实现的。

1.2 实验平台介绍Visual C++(简称VC)是Microsoft公司推出的目前使用极为广泛的基于Windows 平台的C++可视化开发环境。

VC基于C,C++语言,主要由是MFC组成,是与系统联系非常紧密的编程工具,它兼有高级,和低级语言的双重性,功能强大,灵活,执行效率高,几乎可说VC在 Windows平台无所不能。

c网络聊天室课程设计

c网络聊天室课程设计

c 网络聊天室课程设计一、教学目标本课程旨在让学生了解网络聊天室的基本原理和功能,掌握C语言在网络编程中的应用,培养学生具备网络编程的基本能力和解决实际问题的能力。

具体目标如下:1.知识目标:(1)了解网络聊天室的基本概念和原理;(2)掌握C语言在网络编程中的基本方法;(3)理解网络编程中的Socket编程和TCP/IP协议。

2.技能目标:(1)能够使用C语言编写简单的网络聊天室程序;(2)能够分析和解决网络编程中的基本问题;(3)能够运用所学知识,独立完成网络编程项目。

3.情感态度价值观目标:(1)培养学生对网络编程的兴趣和热情;(2)培养学生团队协作和自主学习的能力;(3)培养学生具备良好的网络编程道德和法律法规意识。

二、教学内容本课程的教学内容主要包括以下几个部分:1.网络聊天室的基本概念和原理:介绍网络聊天室的定义、功能和应用场景。

2.C语言在网络编程中的应用:讲解C语言在网络编程中的基本方法,如Socket编程、TCP/IP协议等。

3.网络编程实践:通过案例教学,让学生动手编写网络聊天室程序,培养实际操作能力。

4.项目实践:学生分组完成网络编程项目,提高团队协作和解决实际问题的能力。

三、教学方法为了提高教学效果,本课程将采用以下教学方法:1.讲授法:讲解网络聊天室的基本概念、原理和方法。

2.案例分析法:分析典型网络聊天室程序,让学生了解实际应用。

3.实验法:让学生动手编写网络聊天室程序,培养实际操作能力。

4.讨论法:分组讨论项目实践中的问题,提高团队协作和解决问题的能力。

四、教学资源为了支持教学内容和教学方法的实施,我们将准备以下教学资源:1.教材:《C语言网络编程教程》等。

2.参考书:《网络编程技术手册》、《TCP/IP协议详解》等。

3.多媒体资料:网络聊天室程序示例、教学视频等。

4.实验设备:计算机、网络设备等。

五、教学评估本课程的教学评估将采用多元化的评价方式,全面客观地评价学生的学习成果。

多线程聊天室课程设计

多线程聊天室课程设计

多线程聊天室课程设计一、课程目标知识目标:1. 理解多线程编程的基本概念,掌握线程的创建、同步和通信方法;2. 了解网络编程中客户端与服务器之间的通信原理,掌握套接字编程技术;3. 学会使用所学知识设计并实现一个多线程聊天室程序。

技能目标:1. 能够运用所学多线程编程技术,独立编写并调试简单的多线程程序;2. 能够利用套接字编程技术实现客户端与服务器之间的数据传输;3. 能够通过小组合作,共同完成一个具有实际应用价值的聊天室项目。

情感态度价值观目标:1. 培养学生对计算机编程的兴趣和热情,提高他们主动学习的积极性;2. 培养学生的团队合作精神,学会在项目中相互协作、共同进步;3. 培养学生具备解决问题的能力,面对编程挑战时,能够勇于尝试、不断调试,直至问题解决。

课程性质:本课程为信息技术学科选修课程,旨在让学生掌握多线程编程和网络编程的基础知识,通过实际项目设计,提高编程实践能力。

学生特点:学生处于高年级阶段,已具备一定的编程基础和逻辑思维能力,对实际项目具有较强的兴趣。

教学要求:结合学生特点,注重理论与实践相结合,以项目驱动教学,让学生在实践过程中掌握多线程聊天室的设计与实现。

同时,关注学生的个体差异,给予个性化的辅导与指导,确保每个学生都能在课程中取得进步。

通过教学评估,检验学生是否达到预设的课程目标。

二、教学内容1. 多线程编程基础:- 线程的概念与创建方法;- 线程的同步与互斥;- 线程的通信与协作。

2. 网络编程基础:- 网络协议与网络模型;- 套接字编程原理;- 客户端与服务器通信过程。

3. 聊天室项目设计与实现:- 项目需求分析与功能设计;- 多线程聊天室服务器端编程;- 多线程聊天室客户端编程;- 聊天室程序测试与优化。

教学大纲安排:第一课时:多线程编程基础,学习线程的概念、创建方法及同步互斥技术;第二课时:网络编程基础,了解网络协议、套接字编程原理;第三课时:聊天室项目需求分析与功能设计,明确项目目标;第四课时:多线程聊天室服务器端编程,实践多线程与网络编程技术;第五课时:多线程聊天室客户端编程,实践客户端与服务器端的通信;第六课时:聊天室程序测试与优化,对项目进行测试并不断完善。

(VC+MFC网络聊天工具)详细设计

(VC+MFC网络聊天工具)详细设计

第2章系统分析及开发技术说明2.1节需求分析2。

1.1节功能需求分析图2.1 功能需求说明图(1)用户端的基本聊天信息发送,这些基本聊天信息包括文本和图片。

文本和图片聊天是聊天软件最基础的功能.用户通过输入IP来查找用户,并申请加为好友,在对方同意加为好友后,在线用户列表就会更新用户,把加入的用户添加到用户列表中。

这样,两个用户之前就可以实现通信了。

在信息传输中,预计利用TCP/IP协议中的UDP协议,这是面向无连接的协议,但发送速度快,用于聊天信息传输用适合。

(2)用户端的音视频数据传输,这是本设计的扩展功能。

用户可以正常通信后,就可以选择是否进行语音或视频聊天。

本功能也将采用UDP协议,UDP协议可能会丢失数据,但对于音视频聊天需要传输大量数据但又允许丢失少量数据的情况下,UDP的快速发送信息的特点就得到很好的体现。

(3)用户端文件传输的功能,用户之间可以断点续传文件。

在传文件之前,首先创建一信息文件,记录文件传送的一些信息,并根据传输的数据量实时修改。

如果没有传完,下次就可以继续打开这个信息文件,接着上次的进度传输。

因为文件传输入要求数据不能出错,因此此模块采用TCP协议。

(4)用户端之间白板和共享屏幕的功能,这个功能有些类似视频的传输,因些并不是很难,可以在视频传输的功能上加以修改。

(5)用户之间后台的连接,每个用户隔指定时间会向用户列表中的每一用户发送消息,查看用户是否在线,如果不在线,就更新用户列表,删除用户。

2。

1。

2节数据需求分析(1)客户端之间聊天信息。

在控件上显示时格式化,更易于用户的查看自己发送或接收到的信息。

(2)在线用户列表信息.服务器端存放在适当的空间中,在发送给客户端时,对信息列表进行格式化,便于客户端提取信息。

(3)客户端向服务器端发送的确认在线信息。

包括客户端刚刚启动时的初始化信息和在使用过程中的确认在线信息.(4)其它程序内部可能需要设计的数据结构体.2。

1。

c聊天室课程设计

c聊天室课程设计

c 聊天室课程设计一、课程目标知识目标:1. 学生能理解并掌握网络聊天室的基本概念与功能。

2. 学生能了解网络交流中的基本礼仪及网络安全相关知识。

3. 学生掌握使用聊天软件进行文字、表情等基础沟通方式。

技能目标:1. 学生能够独立注册、登录聊天室,进行基本的交流操作。

2. 学生能够运用所学网络礼仪,进行文明、有序的网络交流。

3. 学生能够辨别网络聊天中的潜在风险,保护个人隐私。

情感态度价值观目标:1. 培养学生积极健康的网络交流态度,增强网络责任感。

2. 提高学生对网络暴力的认识,树立正确的网络道德观念。

3. 培养学生团队协作精神,尊重他人,平等交流。

本课程针对五年级学生,结合学科知识,注重网络聊天室的实用性和安全性,旨在帮助学生掌握网络交流的基本技能,提高网络素养,培养良好的网络行为习惯。

课程目标具体、明确,便于学生和教师在教学过程中进行评估和调整。

二、教学内容1. 网络聊天室概念与功能介绍:讲解聊天室的定义、类型及其在网络交流中的应用。

- 教材章节:信息技术课本第四章第三节2. 网络交流礼仪与安全知识:学习网络聊天中的文明用语、隐私保护及识别网络诈骗等内容。

- 教材章节:信息技术课本第四章第四节3. 聊天软件操作技巧:教授如何注册、登录聊天室,使用文字、表情等进行交流。

- 教材章节:信息技术课本第四章第五节4. 网络责任感与道德观念:讨论网络暴力、谣言传播等现象,引导学生在网络世界中树立正确的道德观念。

- 教材章节:信息技术课本第四章第六节5. 实践活动:组织学生进行聊天室模拟演练,分组讨论网络聊天中可能遇到的问题及解决方法。

- 教材章节:信息技术课本第四章实践活动教学内容根据课程目标进行选择和组织,确保科学性和系统性。

教学大纲明确,教学内容与教材章节紧密关联,便于学生理解和掌握。

在教学过程中,教师将引导学生积极参与,提高课堂互动效果。

三、教学方法本课程将采用以下多元化的教学方法,以激发学生的学习兴趣和主动性,提高课堂效果:1. 讲授法:通过讲解网络聊天室的基本概念、功能及相关知识,为学生奠定扎实的理论基础。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

课程设计书学院计算机学院专业计算机科学与技术班级题目局域网聊天室程序教师学生课程设计任务书目录摘要 (3)1 引言 (4)1.1课题背景及意义 (4)1.2 实验平台介绍 (4)1.3 可行性分析 (4)2需求分析 (6)2.1 设计目的 (6)2.2 设计要求 (6)2.3 功能要求 (6)2.4 系统主要功能和主要功能描述 (6)3设计流程图 (8)4 调试分析过程描述 (10)5核心代码 (17)5.1服务端 (17)5.2客服端 (22)6 设计的总结和体会 (25)7 参考文献 (25)局域网聊天室程序摘要计算机网络技术发展至今已经大大超越了人们当初的预想,无论是人们日常的工作还是学习,我们都越来越多的依靠到互联网。

各种实时性的聊天娱乐软件也同时诞生,而且为我们的即时通讯带来了众多的方便,比如说大家所熟知的腾讯QQ、微软的MSN、移动的Fetion等,都是做的比较成功的实时聊天工具。

随着网络的日益普及,各种聊天工具也层出不穷,但当我们学习了《windows程序设计》这门课程之后,我们决定设计一个简单的聊天系统来巩固我们的学习。

接下来的课程设计就是针对一个简单的网络聊天程序,利用MFC为开发工具,实现基本的通讯功能。

在课程设计中,系统开发平台为Windows XP,程序设计设计语言采用Visual C++,数据库采用Access,程序运行平台为Windows 98/2000/XP。

关键词聊天软件;局域网;MFC; Visual C++;多线程1 引言1.1课题背景及意义当今世界正处于信息时代,计算机和通信网络是这一时代所谓“信息基础设施”。

在互联网相当普及的今天,在互联网上聊天对很多“网虫”来说已经是家常便饭了。

聊天室程序可以说是网上最简单的多点通信程序。

一个简单的聊天室, 从程序员的观点来看就是在多个I/O端点之间实现多对多的通信。

基于SOCKET的局域网通信是一种灵活的、易于实现的、低成本的方法。

它可以运行在各种使用TCP/IP协议作为通讯协议的网络上。

而在SOCKET API的帮助下,开发基于SOCKET的局域网通信软件也是易于实现的。

1.2 实验平台介绍Visual C++(简称VC)是Microsoft公司推出的目前使用极为广泛的基于Windows平台的C++可视化开发环境。

VC基于C,C++语言,主要由是MFC组成,是与系统联系非常紧密的编程工具,它兼有高级,和低级语言的双重性,功能强大,灵活,执行效率高,几乎可说VC在Windows平台无所不能。

VC主要是针对Windows系统,适合一些系统级的开发,可以方便实现一些底层的调用。

在VC里边嵌入汇编语言很简单。

当对系统性能要求很高的时候,可用VC开发。

VC在多线程、网络通信、分布应用方面,有着不可比拟的优势。

1.3 可行性分析本课程设计主要解决在客户端于客户端的信息交换和客户端于服务器的信息交换及服务器的信息处理上的管理的课程设计。

此程序主要分为两部分:服务器端和客户端。

服务器端用于提供一个网络端口,等待客户端发出请求,登录到此服务端,然后进行网络通讯和消息的转发;客户端可通过服务器端的IP地址发送连接请求,然后登陆聊天室。

在服务器端的成员列表栏中会显示在线的所有人名单,有人退出聊天室,成员列表会自动除名。

服务器端同时也提供了成员之间的私聊功能,此时服务器端作为一个转发站,进行消息的转发。

整个程序的主体使用了CSocket类的方法,实现了网络通讯聊天。

先启动服务器端聊天程序,这是聊天服务器需要指定一个端口号,客户端则根据这个端口号以及服务器的网络地址与服务器进行通信。

在这里,把端口号成为“聊天频道”。

在后面的程序代码分析中将看到,端口号并不等同于聊天频道,而是在聊天频道上增加一个固定的偏移值,使得这个聊天频道不会和系统保留的端口发生冲突。

服务器启动后将在这个指定的端口号中等待客户的连接。

对于公共聊天室,服务器对客户的数目不做任何限制。

而对于私人聊天室,每个聊天频道则只能允许两个客户互相连接,使得一方发送的信息只能到达对方的主机中。

这里的服务器提供的是公共聊天服务。

通过分析发现,该程序完全可以通过Visual C++中MFC完成。

2需求分析2.1 设计目的综合运用本课程及计算机网络的相关知识设计并实现一个网络应用程序,以Visual C++作为开发平台,通过实践复习巩固课堂所学的理论知识,提高对所学知识的综合应用能力。

2.2 设计要求采用客户/服务器模式,分为客户端程序和服务器端程序。

服务器采用WINSOCK I/O 模型中的任一种,支持多个客户同时在线聊天。

客户端程序和服务器程序通过网络交换聊天字符串内容,服务器窗口的列表框中显示当前在线用户,支持客户端之间的私聊(可以通过服务器中转,或考虑UDP打洞直接建立端端连接)。

课程设计要求设计并编程完成两个方面的内容:首先建立一个使用TCP协议的聊天室服务器,这个服务器可以同时支持多个用户的在线聊天;其次设计一个可以和服务器通信的聊天室客户端。

2.3 功能要求✧支持多个客户端的连接,在服务器和多个客户端之间进行数据传输;✧接收客户端发送的消息,并显示在一个列表框中;✧在用户连接上后有提示,显示出连接的用户名字;✧发送信息时可以显示聊天的所有记录;2.4 系统主要功能和主要功能描述服务器端聊天程序必须能够做3件事情:(1)服务器聊天程序要在待定的端口上等待来自聊天客户的连接请求,并且需要维护一个客户连接表,以记录所有成功的连接。

(2)服务器聊天程序要及时接受从各个聊天客户发送过来的信息,然后把这些信息转发到一个或多个客户连接。

对于公共聊天室,服务器将把接受到的信息向除源端外的所有客户发送过去。

(3)服务器还要监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相应的表项,并及时更新连接表。

客户端聊天程序需要完成以下几个功能:(1)客户端聊天程序要负责建立和维护与服务器的连接,通过获取用户的设置尝试与服务器的连接,并且随时检测连接的状态。

(2)客户端聊天程序要把用户输入的信息及时发送到聊天服务器。

一般情况下,当用户输入一行信息并且按下回车键后聊天程序就要把这一行信息发送出去,才能及时地满足用户的交互需求。

(3)要随时准备好接受来自服务器的信息,随时把接受到的信息显示出来,让用户及时看到对方的响应。

(4)在用户退出聊天过程是要关闭与服务器的连接。

比较好的做法是提前通知服务器或者直接给服务器发送一条退出通知,使得服务器能够及时掌握客户端的连接状态,把对方客户的退出信息及时发送到对等实体上。

3设计流程图根据对用户的要求及功能设置可以得到以下的流程图3.1,用户首先启动客户端,登陆服务器并向服务器发送信息,启动服务器,服务器等待客户要求并向客户反馈在线用户信息,用户向服务器发送信息,服务器处理用户的数据,然后用户开始聊天。

客户端的聊天分为对所有人的信息和私聊的信息,该信息应通过程序控制分别进行处理。

图3.1 设计流程图4 调试分析过程描述⏹在聊天客服端启动的时候对端口进行监听,会出现图4.1的界面。

图4.1登陆服务器界面⏹在客户端启动的时候,会出现图4.2的界面,该界面为客户端的连接界面。

图4.2 登陆客户端界面(客服端1)图4.2 登陆客户端界面(客服端2)图4.3为用户张三和李四连接服务器时的界面图4.3 张三登陆服务器图4.3李四登陆服务器 图4.4为用户李四发送消息的服务器界面图4.4 李四发送消息服务端界面 图4.5为用户张三发送消息的服务器界面图4.4 张三发送消息服务端界面 图4.6为用户李四发送消息的客服端界面图4.6李四发送消息的客服端界面 图4.7为用户张三发送消息的客服端界面图4.7张三发送消息的客服端界面5核心代码5.1服务端(1).启动监听UpdateData(TRUE); //更新数据到类成员GetDlgItem(IDC_BTNSTART)->EnableWindow(FALSE);GetDlgItem(IDC_BTNSEND)->EnableWindow(TRUE);g_ServerSocket=socket(AF_INET,SOCK_STREAM,0); //创建套接字if( INVALID_SOCKET == g_ServerSocket){MessageBox("创建套接字失败!");return ;}SOCKADDR_IN svraddrsock;svraddrsock.sin_addr.S_un.S_addr=htonl(INADDR_ANY);svraddrsock.sin_family=AF_INET;svraddrsock.sin_port=htons(m_port);if ( SOCKET_ERROR ==bind(g_ServerSocket,(SOCKADDR*)&svraddrsock,sizeof(SOCKADDR))) {MessageBox("套接字绑定失败!");return ;}listen(g_ServerSocket,10); //监听套接字//创建接收线程m_hAcceptthread=CreateThread(NULL,0,AcceptThread,NULL,0,NULL);if (m_hAcceptthread ==NULL){MessageBox("创建接收连接线程失败!");return ;}g_hmutex=CreateMutex(NULL,FALSE,NULL); //创建互斥量(2).监听请求连接线程//接收连接DWORD WINAPI AcceptThread( LPVOID lpParameter){SOCKADDR_IN serveraddr;int addrlen=sizeof(SOCKADDR);SOCKET RecvSocket;//recv后返回的套接字RecvSocket=accept(g_ServerSocket,(SOCKADDR *)&serveraddr,&addrlen);g_ClientSocket = RecvSocket;if ( INVALID_SOCKET==RecvSocket){AfxMessageBox("接受连接失败!");return FALSE;}BOOL ContinueFlag=TRUE;while (ContinueFlag&&TRUE){g_Mutex.Lock();BYTE recvBuff[RECV_DATA_SIZE + 2]={0};int recvlength=sizeof(recvBuff);int recvedSize = 0;recvedSize = recv(RecvSocket,(char*)recvBuff,recvlength,0);if(SOCKET_ERROR == recvedSize){int x=WSAGetLastError();CString str;//WSANOTINITIALISEDstr.Format("错误代码:%d", x);AfxMessageBox(str);break ;}CStringArray RecvData;UINT CmdFlag;CChatRoomServerDlg::Split((char*)recvBuff,'|',RecvData); //将收到的数据进行分离if (RecvData.GetSize()<=0){continue ;}CmdFlag=atoi(RecvData.GetAt(0).GetBuffer(RecvData.GetAt(0).GetLength()));int i=0; //记录循环次数的变量BOOL comeFlag=TRUE ;//是否加入用户列表的标记CTime iotime;CString StrRecord=""; //聊天内容CString strTemp="";CString strTemp1="";char sendBuff[1024]={0};int j=0;CChatRoomServerDlg *ServerDlg=(CChatRoomServerDlg *)AfxGetApp()->GetMainWnd();//解析客服端发来的消息以便确定消息的类型switch(CmdFlag){case CONNECT: //用户发来的连接请求//对用户发来的用户名和密码进行判断strTemp = CString(RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()));ZeroMemory(sendBuff,1024);//将JOIN命令和用户名填入缓冲区sprintf(sendBuff,"5|%s|",RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()));for( i=0;i<count;i++) //向除自己以外的所有在线用户发送一条加入消息{//SOCKET tempsocket = ((UserInfo *)UserList.GetAt(j))->UserSocket;if (RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()) !=User[i].UserName){if(SOCKET_ERROR ==send(User[i].UserSocket,sendBuff,strlen(sendBuff),0)){AfxMessageBox("connect 中向各用户发送消息失败!");break;}}}//向该用户发送一条LIST消息使其将所有在线用户加入用户列表ZeroMemory(sendBuff,1024);strTemp="3|";for(i=0;i<count;i++){if (RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()) !=User[i].UserName){strTemp+=User[i].UserName;strTemp+="|";}}sprintf(sendBuff,"%s",strTemp);if(count>0){if(SOCKET_ERROR ==send(RecvSocket,sendBuff,strlen(sendBuff),0)){AfxMessageBox("connect中发送List数据失败!");break ;}}//将该用户加入用户列表for(i=0;i<count;i++){if (RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()) ==User[i].UserName){comeFlag=FALSE;}}if (comeFlag){User[count].UserName=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength());User[count].UserSocket=RecvSocket;count++;}//将用户登陆成功发送给用户ZeroMemory(sendBuff,1024);sprintf(sendBuff,"1|%s|",RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()));if( SOCKET_ERROR ==send(RecvSocket,sendBuff,strlen(sendBuff),0)){AfxMessageBox("CONNECT中向客户端发送登陆成功消息失败!");break ;}//在服务器上加入用户信息ServerDlg->AddToUserList(RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()));//将用户加入用户列表strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength());iotime=CTime::GetCurrentTime();strTemp1=iotime.Format(" 于:%Y年%m月%d日%H:%M:%S登录");strTemp+=strTemp1;strTemp1="服务器";ServerDlg->SetChatRecord(strTemp1,strTemp);break;case CHAT: //群聊ZeroMemory(sendBuff,1024);//向所有其他在线的用户转发收到的消息sprintf(sendBuff,"2|%s|%s|",RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()),RecvData.GetAt(2).GetBuffer(RecvData.GetAt(2).GetLength()));for( i=0;i<count;i++){if (RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()) !=User[i].UserName){send(User[i].UserSocket,sendBuff,strlen(sendBuff),0);}}// 将收到的消息显示在服务器消息记录框中ServerDlg->SetChatRecord(RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()),RecvData.GetAt(2).GetBuffer(RecvData.GetAt(2).GetLength()));break;case EXIT:for(i=0;i<count;i++) //删除用户在UserList中的信息{if(RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength())==User[i].UserName){//UserList.RemoveAt(i);for(j=i;j<count;j++){User[j].UserName=User[j+1].UserName;User[j].UserSocket=User[j+1].UserSocket;}}}//把退出的用户从服务器用户列表中删除,同时向聊天记录中更新一条退出的消息strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength());ServerDlg->DeleteFromUserList(strTemp);//将用户从服务器“用户列表”中删除iotime=CTime::GetCurrentTime();strTemp1=iotime.Format(" 于:%Y年%m月%d日%H:%M:%S下线");strTemp+=strTemp1;strTemp1="服务器";ServerDlg->SetChatRecord(strTemp1,strTemp);//向其他用户发送QUit消息ZeroMemory(sendBuff,1024)sprintf(sendBuff,"6|%s|",RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()));for( i=0;i<count;i++){if (RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength()) !=User[i].UserName){send(User[i].UserSocket,sendBuff,strlen(sendBuff),0);}}ContinueFlag=FALSE;break;default :strTemp="无法识别的指令!";strTemp1="服务器";ServerDlg->SetChatRecord(strTemp1,strTemp);break;}RecvData.RemoveAll();g_Mutex.Unlock();Sleep(10);}return TRUE;}5.2客服端(1).建立连接UpdateData(TRUE);if (m_username.IsEmpty()||m_pwd.IsEmpty()){MessageBox("用户名或密码不能为空!");return ;}g_ClientSocket=socket(AF_INET,SOCK_STREAM,0); //创建套接字if( INVALID_SOCKET == g_ClientSocket){MessageBox("创建套接字失败!");return ;}DWORD dwIP;((CIPAddressCtrl *)GetDlgItem(IDC_IPADDRESS1))->GetAddress(dwIP);SOCKADDR_IN clientaddr;clientaddr.sin_family=AF_INET;clientaddr.sin_port=htons(m_port);clientaddr.sin_addr.S_un.S_addr=htonl(dwIP);if ( SOCKET_ERROR ==connect(g_ClientSocket,(SOCKADDR *)&clientaddr,sizeof(SOCKADDR))) {MessageBox("连接服务器失败!");return ;}char sendBuff[1024]={0};sprintf(sendBuff,"1|%s|%s|",m_username.GetBuffer(m_username.GetLength()),m_pwd.GetBuffer(m_ pwd.GetLength()));int sendlength=strlen(sendBuff);if ( SOCKET_ERROR == send(g_ClientSocket,sendBuff,sendlength,0)) //连接成功后将用户名和密码发给服务器{MessageBox("发送连接请求数据失败!");return ;}hRecvThread=CreateThread(NULL,0,RecvThread,NULL,0,NULL); //创建客户端接收数据线程GetDlgItem(IDC_BTNSEND)->EnableWindow(TRUE);GetDlgItem(IDC_USERLOAD)->EnableWindow(FALSE);(2).接受数据线程DWORD WINAPI RecvThread(LPVOID lpParameter){while (TRUE){g_Mutex.Lock();BYTE recvBuff[RECV_DATA_SIZE + 2]={0};int bufflength=sizeof(recvBuff);int recvedSize = 0;//Sleep(100);recvedSize = recv(g_ClientSocket,(char*)recvBuff,bufflength,0);if ( SOCKET_ERROR == recvedSize){AfxMessageBox("接收数据失败!");break ;}CStringArray RecvData;CChatRoomClientDlg::Split((char*)recvBuff,'|',RecvData); //此函数不会分解AUDIO命令,直接交个case处理if (RecvData.GetSize()<=0){continue ;}UINT CmdFlag=atoi(RecvData.GetAt(0).GetBuffer(RecvData.GetAt(0).GetLength()));int i=0; //循环时使用的增加量CString strRecord="";CString strTemp="";CChatRoomClientDlg *ClientDlg=(CChatRoomClientDlg *)AfxGetApp()->GetMainWnd();switch( CmdFlag){case OK:strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength());strRecord="登陆成功";ClientDlg->SetChatRecord(strTemp,strRecord);break;case CHAT: //群聊strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength());strRecord=RecvData.GetAt(2).GetBuffer(RecvData.GetAt(2).GetLength());ClientDlg->SetChatRecord(strTemp,strRecord);breakcase LIST:for(i=1;i<RecvData.GetSize();i++){strTemp=RecvData.GetAt(i).GetBuffer(RecvData.GetAt(i).GetLength());ClientDlg->AddToUserList(strTemp);}break;case PRIVATE:strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength());strTemp+="悄悄地对你";strRecord=RecvData.GetAt(2).GetBuffer(RecvData.GetAt(2).GetLength());ClientDlg->SetChatRecord(strTemp,strRecord);break;case JOIN :strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength());ClientDlg->AddToUserList(strTemp);break;case QUIT:strTemp=RecvData.GetAt(1).GetBuffer(RecvData.GetAt(1).GetLength());ClientDlg->DeleteFromUserList(strTemp);break;default:strTemp="服务器";strRecord="无法识别的指令";ClientDlg->SetChatRecord(strTemp,strRecord);if (g_ClientSocket){closesocket(g_ClientSocket);}break;}RecvData.RemoveAll();g_Mutex.Unlock();Sleep(10);}return TRUE;}(3).发送数据char sendBuff[1024]={0};CString sendMsg="";CString strTemp="";GetDlgItemText(IDC_EDIT_MSG,sendMsg);if (sendMsg.IsEmpty()){return ;}//将发送的内容发给服务器sprintf(sendBuff,"2|%s|%s|",m_username,sendMsg.GetBuffer(sendMsg.GetLength()));if(SOCKET_ERROR==send(g_ClientSocket,sendBuff,strlen(sendBuff),0)){MessageBox("数据发送失败!");return ;}//将发送的内容更新到自己的聊天记录中GetDlgItemText(IDC_EDITCHATMSG,strTemp);strTemp+="\r\n";strTemp+=m_username;strTemp+="说:";strTemp+=sendMsg;SetDlgItemText(IDC_EDITCHATMSG,strTemp);SetDlgItemText(IDC_EDIT_MSG,"");6 设计的总结和体会通过这学期对windows的学习以及以往对window程序设计的理解并在学校图书馆查阅相关资料,最终通过大家的努力完成了这个简单的局域网通信程序。

相关文档
最新文档