




免费预览已结束,剩余18页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
VC6.0作的“服务器和客户端”的程序的详细操作步骤实验四:基于TCP的Socket应用程序(MFC)教材上是在win32下手动添加的代码。这个程序是基于对话框的MFC应用程序。(一) 服务器端应用程序操作过程1、新建“MFC APPWIZARD(EXE)”,选择文件路径,输入文件名 在第一步中选择应用程序类型为“基本对话框” 在第二步中选中“windows sockts支持”2、添加各控件1)添加一个文本框控件,主要用来设置服务器的端口,ID号为IDC_ServerPort2)添加一个标准按钮控件,用来开启服务器,实现监听功能,ID号为IDC_Start,标题为开启服务3)添加一个标准按钮控件,用于结束服务器服务,ID号为IDC_End,标题为结束服务4)添加一个标准按钮控件,用于退出服务器应用程序,ID号为IDC_Exit,标题为退出程序5)添加一个标准按钮控件,用于清空服务器端的记录信息,ID号为IDC_Clear,标题为清空信息6)添加一个列表框控件(List Box),用于记录计算机间的聊天信息,ID号为IDC_Chat7)添加相应的静态文本控件,如下图所示:3、为各控件添加成员变量ID号类型成员变量IDC_ServerPortintm_iPortCEditm_ctlPortIDC_StartCButtonm_btnStartIDC_EndCButtonm_ctlEndIDC_ExitCButtonm_ctlExitIDC_ClearCButtonm_ctlClearIDC_ChatCstringm_strChatCListBoxm_lstChat4、设计CAsyncSocket的派生类CSocketListen1)新建类CSocketListen,选择基类为CAsyncSocket2)在SocketListen.h中添加代码(粗体字为添加的代码)class CSocketListen : public CAsyncSocket/ Attributespublic:/ Operationspublic:CSocketListen();virtual CSocketListen();/ Overridespublic:/自定义函数,用来设置该类与对话框关联void SetParent(CDialog *pWnd);/void operator=(const CSocketListen& rSrc);/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CSocketListen)/AFX_VIRTUAL/ Generated message map functions/AFX_MSG(CSocketListen)/ NOTE - the ClassWizard will add and remove member functions here./AFX_MSGprivate:CDialog *m_pWnd;/ Implementationprotected:virtual void OnAccept(int nErrorCode);virtual void OnClose(int nErrorCode);virtual void OnReceive(int nErrorCode);virtual void OnSend(int nErrorCode);3)在SocketListen.cpp中添加代码(粗体字为添加的代码)#include stdafx.h#include 实验四服务器端.h#include SocketListen.h#include 实验四服务器端Dlg.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ CSocketListenCSocketListen:CSocketListen()CSocketListen:CSocketListen()/ Do not edit the following lines, which are needed by ClassWizard.#if 0BEGIN_MESSAGE_MAP(CSocketListen, CAsyncSocket)/AFX_MSG_MAP(CSocketListen)/AFX_MSG_MAPEND_MESSAGE_MAP()#endif/ 0/ CSocketListen member functions/自定义事件,设置与对话框的关联void CSocketListen:SetParent(CDialog *pWnd)m_pWnd = pWnd;/下列的Socket事件,设置其与对话框相关联,重载代码如下:void CSocketListen:OnAccept(int nErrorCode) if (0=nErrorCode)/响应socket请求连接的事件(CMyDlg *)m_pWnd)-OnAccept();void CSocketListen:OnClose(int nErrorCode) if (0=nErrorCode)/响应socket断开数据的事件(CMyDlg *)m_pWnd)-OnSocketClose(this);void CSocketListen:OnReceive(int nErrorCode) if (0=nErrorCode)/响应socket接收数据的事件(CMyDlg*)m_pWnd)-OnReceive(this);void CSocketListen:OnSend(int nErrorCode) if (0=nErrorCode)/响应socket发送数据的事件(CMyDlg*)m_pWnd)-OnSend();5、分别添加对话框类MyDlg中的函数代码1)添加“实验四服务器端Dlg.h”头文件中的代码(粗体字为添加的代码)#if !defined(AFX_DLG_H_225BCFCC_FE91_46E5_AEFA_32F1A897B88F_INCLUDED_)#define AFX_DLG_H_225BCFCC_FE91_46E5_AEFA_32F1A897B88F_INCLUDED_#include SocketListen.h/头文件#if _MSC_VER 1000#pragma once#endif / _MSC_VER 1000/ CMyDlg dialogclass CMyDlg : public CDialog/ Constructionpublic:CMyDlg(CWnd* pParent = NULL);/ standard constructor/声明如下四个函数跟SocketListen类的事件关联。void OnSend();/函数传递CSocketListen指针类型的参数,其目的是:在连接多个客户端应用程序时,根据该参数能确定究竟是哪个连接socket在产生网络事件,从而能够有针对地处理数据void OnReceive(CSocketListen *pSocket);void OnSocketClose(CSocketListen *pSocket);void OnAccept();/ Dialog Data/AFX_DATA(CMyDlg)enum IDD = IDD_MY_DIALOG ;CButtonm_ctlExit;CButtonm_btnStart;CButtonm_ctlEnd;CButtonm_ctlClear;CListBoxm_lstChat;CEditm_ctlPort;intm_iPort;CStringm_strChat;/AFX_DATA/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CMyDlg)protected:virtual void DoDataExchange(CDataExchange* pDX);/ DDX/DDV support/AFX_VIRTUAL/ Implementationprotected:HICON m_hIcon;/ Generated message map functions/AFX_MSG(CMyDlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnStart();afx_msg void OnEnd();afx_msg void OnExit();afx_msg void OnClear();/AFX_MSGDECLARE_MESSAGE_MAP()public: CSocketListen m_sListenSocket;/定义用于监听的socket对象/定义链表,用来存储不同的客户端请求所产生的连接socket对象指针/要使用链表模板类,需要在StdAfx头文件中加入以下语句#include CList m_sAcceptSocketA;2)在“实验四服务器端Dlg.cpp”中添加消息函数的代码l 单击类视图中CmyDlg类中CMyDlg(CWnd* pParent /*=NULL*/)函数,添加CMyDlg(CWnd* pParent /*=NULL*/)函数的代码(粗体字为添加的代码)CMyDlg:CMyDlg(CWnd* pParent /*=NULL*/): CDialog(CMyDlg:IDD, pParent)/AFX_DATA_INIT(CMyDlg)m_iPort = 0;m_strChat = _T(); m_iPort = 1001;/初始化服务器程序设置端口的文本框控件/AFX_DATA_INIT/ Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()-LoadIcon(IDR_MAINFRAME);l 单击类视图中CmyDlg类中OnInitDialog()函数,添加OnInitDialog()函数的代码BOOL CMyDlg: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 AppendMenu(MF_SEPARATOR);pSysMenu-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);/ Set the icon for this dialog. The framework does this automatically/ when the applications main window is not a dialogSetIcon(m_hIcon, TRUE);/ Set big iconSetIcon(m_hIcon, FALSE);/ Set small icon/ TODO: Add extra initialization here/设置窗体标题,/AfxGetApp()-m_pMainWnd-SetWindowText();简写如下条语句。SetWindowText(服务器端程序); /将自定义的SocketListen类与对话框相关联m_sListenSocket.SetParent(this);/m_sAcceptSocket.SetParent(this);/初始的时候,“结束服务”按钮不可用m_ctlEnd.EnableWindow(false);return TRUE; / return TRUE unless you set the focus to a controll 双击“开启服务”按钮,添加OnStart()函数的代码/获取端口号void CMyDlg:OnStart() / TODO: Add your control notification handler code here/获取端口号UpdateData(true);/服务开启后,端口号和该按钮禁用m_ctlPort.EnableWindow(false);m_btnStart.EnableWindow(false);/“结束服务”按钮可用m_ctlEnd.EnableWindow(true);/创建服务器端套接字,Create函数的第二个关键字指明基于TCP协议m_sListenSocket.Create(m_iPort, SOCK_STREAM);m_sListenSocket.Listen();l 双击“结束服务”按钮,添加OnEnd ()函数的代码void CMyDlg:OnEnd() / TODO: Add your control notification handler code herem_sListenSocket.Close();int i;for(i=0; iClose();/m_sAcceptSocket.Close();/结束服务后,端口号和开启服务的按钮可用m_ctlPort.EnableWindow(true);m_btnStart.EnableWindow(true);/“结束服务”按钮不可用m_ctlEnd.EnableWindow(false);l 双击“退出程序”按钮,添加OnExit ()函数的代码void CMyDlg:OnExit() / TODO: Add your control notification handler code hereOnEnd();CDialog:OnOK();l 双击“清空信息”按钮,添加OnClear ()函数的代码void CMyDlg:OnClear() / TODO: Add your control notification handler code here/清空列表框内容m_lstChat.SendMessage(LB_RESETCONTENT,0,0);3)在“实验四服务器端Dlg.cpp”中添加与派生的CsocketListen类相关的事件函数的代码/与Socket类相关的事件函数void CMyDlg:OnAccept() /请求连接int i;i = m_sAcceptSocketA.GetCount();CSocketListen *m_sAcceptSocket = new CSocketListen;m_sAcceptSocket-SetParent(this);if(i = 5 | iGetPeerName(strIp, iPort);/如果上条语句执行正确的话,执行下列语句if(iErr != SOCKET_ERROR)/取得网络顺序的IP值dwIp = inet_addr(strIp);/获取主机名称,注意其中第一个参数的转化pHost = gethostbyaddr(LPSTR)&dwIp, 4, AF_INET);memcpy(pName, pHost-h_name, 256);strName = pName;elsedelete pName;return;strSend = strName + + strIp+ : + 已经退出本系统!;iLen = strSend.GetLength();m_sAcceptSocketA.RemoveAt(m_sAcceptSocketA.Find(pSocket);pSocket-Close();/ 通知当前在线的所有用户,有人退出系统!int i, k;k = m_sAcceptSocketA.GetCount();for(i=0; i Send(LPCTSTR(strSend),iLen);delete pName;void CMyDlg:OnReceive(CSocketListen *pSocket) /接收数据char*pBuf = new char1025;intiBufSize = 1024;intiRecvd;CStringstrRecvd;/接收的数据信息字符串intiLen;intiSend;DWORDdwIp;/网络顺序形式的IP地址CString strIp;/连接方IP地址CString strName;/连接方主机名char*pName = new char256;UINTiPort;intiErr;structhostentFAR *pHost;iErr = pSocket-GetPeerName(strIp, iPort);/如果上条语句执行正确的话,执行下列语句if(iErr != SOCKET_ERROR)/取得网络顺序的IP值dwIp = inet_addr(strIp);/获取主机名称,注意其中第一个参数的转化pHost = gethostbyaddr(LPSTR)&dwIp, 4, AF_INET);memcpy(pName, pHost-h_name, 256);strName = pName;elsedelete pBuf;delete pName;return;/ 接收信息,并返回接收到的字节数iRecvd = pSocket-Receive(pBuf, iBufSize);/ m_sAcceptSocket.Receive(pBuf, iBufSize);/ 判断是否有错误发生if (iRecvd = SOCKET_ERROR)delete pBuf;delete pName;return;else/ 利用NULL来截去接收缓存区中多余的字符pBufiRecvd = NULL;/ 将接收到的有用的信息赋值给CString变量strRecvd = pBuf;strRecvd = strName + + strIp+ : + strRecvd;iLen = strRecvd.GetLength();/ 将接收到的信息加入到列表框中去,SendMessage将字符串添加到末尾/m_lstChat.AddString(strRecvd);m_lstChat.SendMessage(LB_INSERTSTRING, -1, (LPARAM)(LPCTSTR(strRecvd);/将对应的变量的变化显示在控件上UpdateData(FALSE);/将接收到的信息转发给每个客户端int i, k;k = m_sAcceptSocketA.GetCount();for(i=0; i Send(LPCTSTR(strRecvd),iLen);delete pBuf;delete pName;(二)客户端应用程序操作过程1、新建工程“MFC APPWIZARD(EXE)”,选择文件路径,输入文件名 在第一步中选择应用程序类型为“基本对话框” 在第二步中选中“windows sockts支持”2、添加各控件1)添加一个文本框控件,用来输入要链接的服务器名,ID号为IDC_ServName2)添加一个文本框控件,用来输入服务器端口号,ID号为IDC_ServPort3)添加一个文本框控件,用来输入要发送的字符串信息,ID号为IDC_Data4)添加一个标准按钮控件,用来连接服务器,ID号为IDC_Connect5)添加一个标准按钮控件,用来断开与服务器的连接,ID号为IDC_DisConnect6)添加一个标准按钮控件,用来退出应用程序,ID号为IDC_Exit7)添加一个标准按钮控件,用来清空聊天信息,ID号为IDC_Clear8)添加一个标占按钮控件,用来发送信息,ID号为IDC_Send9)添加一个列表框控件,用来显示已经发送过来的每条信息,ID号为IDC_Chat10)添加相应静态文本控件,如下图所示:3、为各控件添加成员变量ID号类型成员变量IDC_ChatCStringm_strChatCListBoxm_lstChatIDC_ClearCButtonm_btnClearIDC_ConnectCButtonm_btnConnIDC_DataCStringm_strDataCEditm_ctlDataIDC_DisConnectCButtonm_btnDisconnIDC_ExitCButtonm_btnExitIDC_SendCButtonm_btnSendIDC_ServNameCstringm_strNameCEditm_ctlNameIDC_ServPortintm_iPortCEditm_ctlPort4、设计CAsyncSocket的派生类SocketClient1)新建类SocketClient,选择基类为CAsyncSocket2)添加头文件SocketClient.h的代码(粗体字为添加的代码)class SocketClient : public CAsyncSocket/ Attributespublic:/ Operationspublic:SocketClient();virtual SocketClient();/ Overridespublic:/自定义函数,用来设置该类与对话框关联void SetParent(CDialog *pWnd);/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(SocketClient)/AFX_VIRTUAL/ Generated message map functions/AFX_MSG(SocketClient)/ NOTE - the ClassWizard will add and remove member functions here./AFX_MSGprivate:CDialog *m_pWnd;/定义对话框类的指针变量/ Implementationprotected:virtual void OnClose(int nErrorCode);virtual void OnConnect(int nErrorCode);virtual void OnReceive(int nErrorCode);virtual void OnSend(int nErrorCode);3)添加SocketClient.cpp实现文件部分的代码(粗体字为添加的代码)#include stdafx.h#include 实验四客户端.h#include SocketClient.h#include 实验四客户端Dlg.h /头文件#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endif/ SocketClientSocketClient:SocketClient()SocketClient:SocketClient()/ Do not edit the following lines, which are needed by ClassWizard.#if 0BEGIN_MESSAGE_MAP(SocketClient, CAsyncSocket)/AFX_MSG_MAP(SocketClient)/AFX_MSG_MAPEND_MESSAGE_MAP()#endif/ 0/ SocketClient member functions/自定义事件,设置与对话框的关联void SocketClient:SetParent(CDialog *pWnd)m_pWnd = pWnd;/下列的Socket事件,设置其与对话框相关联,重载代码如下:void SocketClient:OnClose(int nErrorCode) / TODO: Add your specialized code here and/or call the base classif (0=nErrorCode)(CMyDlg*)m_pWnd)-OnSocketClose();void SocketClient:OnConnect(int nErrorCode) / TODO: Add your specialized code here and/or call the base classif(nErrorCode=0)(CMyDlg*)m_pWnd)-OnConnect();void SocketClient:OnReceive(int nErrorCode) / TODO: Add your specialized code here and/or call the base classif(0=nErrorCode)(CMyDlg*)m_pWnd)-OnReceive();void SocketClient:OnSend(int nErrorCode) / TODO: Add your specialized code here and/or call the base classif (0=nErrorCode)(CMyDlg*)m_pWnd)-OnSend();5、分别添加对话框类MyDlg中的函数代码1)添加“实验四客户端Dlg.h”头文件中的代码(粗体字为添加的代码)#if !defined(AFX_DLG_H_B04D474D_A01F_4D51_8808_B5E9D3DF6D0D_INCLUDED_)#define AFX_DLG_H_B04D474D_A01F_4D51_8808_B5E9D3DF6D0D_INCLUDED_#include SocketClient.h/头文件#if _MSC_VER 1000#pragma once#endif / _MSC_VER 1000/ CMyDlg dialogclass CMyDlg : public CDialog/ Constructionpublic:CMyDlg(CWnd* pParent = NULL);/ standard constructor/声明如下四个函数跟SocketClient类的事件关联。void OnSend();void OnReceive();void OnSocketClose();void OnConnect();/ Dialog Data/AFX_DATA(CMyDlg)enum IDD = IDD_MY_DIALOG ;CEditm_ctlPort;CEditm_ctlName;CButtonm_btnSend;CButtonm_btnExit;CButtonm_btnDisconn;CEditm_ctlData;CButtonm_btnConn;CButtonm_btnClear;CListBoxm_lstChat;CStringm_strChat;CStringm_strData;CStringm_strName;intm_iPort;/AFX_DATA/ ClassWizard generated virtual function overrides/AFX_VIRTUAL(CMyDlg)protected:virtual void DoDataExchange(CDataExchange* pDX);/ DDX/DDV support/AFX_VIRTUAL/ Implementationprotected:HICON m_hIcon;/ Generated message map functions/AFX_MSG(CMyDlg)virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();afx_msg void OnExit();afx_msg void OnClear();afx_msg void OnClientConnect();afx_msg void OnDisConnect();afx_msg void OnMsgSend();/AFX_MSGDECLARE_MESSAGE_MAP()private:/定义客户端的SocketSocketClient m_cSocket;2)在“实验四客户端Dlg.cpp”中消息函数的代码l 单击类视图中CmyDlg类中CMyDlg(CWnd* pParent /*=NULL*/)函数,添加CMyDlg(CWnd* pParent /*=NULL*/)函数的代码(粗体字为修改的代码)CMyDlg:CMyDlg(CWnd* pParent /*=NULL*/): CDialog(CMyDlg:IDD, pParent)/AFX_DATA_INIT(CMyDlg)m_strChat = _T();m_strData = _T();m_strName = _T();m_iPort = 1001;/初始化端口/AFX_DATA_INIT/ Note that LoadIcon does not require a subsequent DestroyIcon in Win32m_hIcon = AfxGetApp()-LoadIcon(IDR_MAINFRAME);l 单击类视图中CmyDlg类中OnInitDialog()函数,添加OnInitDialog()函数的代码(粗体字为添加的代码)BOOL CMyDlg: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 AppendMenu(MF_SEPARATOR);pSysMenu-AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);/ Set the icon for this dialog. The framework does this automatically/ when the applications main window is not a dialogSetIcon(m_hIcon, TRUE);/ Set big iconSetIcon(m_hIcon, FALSE);/ Set small icon/ TODO: Add extra initialization here/初始的时候,一些控件是不可用的:m_ctlData.EnableWindow(false);m_btnSend.EnableWindow(false);m_btnDisconn.EnableWindow(false);/设置窗口标题SetWindowText(客户端程序);/设置客户端socket对象与对话框关联m_cSocket.SetParent(this);return TRUE; / return TRUE unless you set the focus to a controll 双击“退出程序”按钮,添加OnExit ()函数的代码void CMyDlg:OnExit() / TODO: Add your control notification handler code hereOnDisConnect();CDialog:OnCancel();l 双击“清除记录”按钮,添加OnClear ()函数的代码void CMyDlg:OnClear() / TODO: Add your control notification handler code here/清空列表框内容m_lstChat.SendMessage(LB_RESETCONTENT,0,0);l 双击“开启服务”按钮,添加OnStart()函数的代码void CMyDlg:OnClear() / TODO: Add your control notification handler code here/清空列表框内容m_lstChat.SendMessage(LB_RESETCONTENT,0,0);为了避免函数名重复,把“连接服务器”按钮的消息相应函数重命名为OnClientConnect
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年下半年黑龙江省水利厅事业单位公开招聘工作人员68人备考考试题库附答案解析
- 2025南平浦城县南浦生态工业园区开发有限公司工程项目管理人员招聘10人备考考试题库附答案解析
- 2025贵州织金县第九中学日语教师临聘备考考试题库附答案解析
- 2025年8月广东深圳市大鹏新区大鹏办事处招聘编外人员3人备考考试题库附答案解析
- 2025河北保定市涞源县招聘社区工作者32人考试参考试题及答案解析
- 2025四川绵阳三台县卫生健康局三台县医疗卫生辅助岗招募52人备考考试题库附答案解析
- 2025年某三甲医院公开招聘医疗岗位工作人员(1人)备考考试题库附答案解析
- 2026中国科学院工程热物理研究所科研部门招聘99人考试参考试题及答案解析
- 基于机器学习的阿德福韦酯费用效益预测模型研究-洞察及研究
- 化肥厂体检福利细则
- 停车位买卖合同电子版
- 2024年安徽九华山旅游发展股份有限公司招聘笔试参考题库附带答案详解
- 梅毒艾滋乙肝三病
- 割灌机安全操作规程培训
- 2024年山西省成考(专升本)大学政治考试真题含解析
- 最高法院第一巡回法庭关于行政审判法律适用若干问题的会议纪要
- 《病历书写基本规范》课件
- 足球场的运营可行性方案
- 重庆市面向西南大学定向选调2024届大学毕业生2024年国家公务员考试考试大纲历年真题3453笔试难、易错历年高频考点荟萃附带答案解析(附后)
- 小学生电力科普小讲座(课件)-小学常识科普主题班会
- 有限合伙份额质押合同完整版(包含质押登记公证手续)
评论
0/150
提交评论