服务器端聊天程序_第1页
服务器端聊天程序_第2页
服务器端聊天程序_第3页
服务器端聊天程序_第4页
服务器端聊天程序_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

聊天工具功能说明:聊天程序由两大部分组成:服务器端聊天程序和客户端聊天程序。服务器端聊天程序负责接收来自客户端的聊天信息,并且根据客户端的要求把这些信息转发给另外一个人或多个聊天客户。客户段聊天程序则负责建立和维护与服务器端的连接,向服务器发送本客户的聊天内容,同时从服务器接收对方的响应。先启动服务器端聊天程序,这时聊天程序需要制定一个端口号,客户端则根据这个端口号以及服务器的网址与服务器进行通信。在这里,把端口号称为“聊天频道”。在后面的程序代码分析中将会看到,端口号并不等同于聊天频道,而是在聊天频道上增加一个固定的偏移值,使得这个聊天频道不会和系统保留的端口发生冲突。服务器启动后将在这个指定的端口中等待客户的链接。对于公共聊天室,服务器对客户的数目不做任何限制。而对于私人聊天室,每个聊天频道则只能允许两个客户互相连接,使得一方发送的信息只能到达对方的主机中。这里的服务器提供的是公共聊天服务。客户端聊天程序启动时,首先需要与聊天服务器建立连接,这就需要知道聊天服务器的网址及聊天频道。聊天服务器都有公开的服务器地址供用户连接。聊天频道则类似于一个个分组,一群爱好相同的人可以选择相同的聊天频道,因而不会受到自己不想要的信息。客户段聊天程序的主窗口分为两个部分:上半部分用来显示来自对方的聊天信息,下半部分用作信息输入窗口。第一部分 服务器端聊天程序一、设计思想和功能服务器端聊天程序必须要能做三件事:1、服务器端聊天程序要在特定的端口上等待来自聊天客户的连接请求,并且需要维护一个客户连接表,已记录所有成功的链接。2、服务器端聊天程序要及时接收从各个聊天客户发来的信息,然后把这些信息转发到一个或多个客户连接。对于公共聊天室,服务器将把接收到的信息向除源端外的所有客户发送过去。3、服务器还要监控这些连接的状态,在客户主动离开或发生故障时从列表中删除相应表项,并及时更新连接表。这些要求可以通过CSocket类提供的功能实现。从CSocket派生出两个类:CListenSocket和CClientSocket,他们分别用来侦听客户的连接请求和建立与客户的连接。服务器只需要一个侦听套接字CListenSocket,然后根据客户的连接请求动态创建客户套接字CClientSocket。客户套接字的数量是不可预知的,因此需要一个列表来记录。的CPtrList类就能实现这种功能。二、程序设计与框架(1)、用MFC AppWizard(exe)创建一个新工程,命名为聊天工具(2)、在MFC AppWizard中按照下述步骤设置工程属性:1)、设置应用程序类型为单文档模式,选择“文档/查看体系结构支持”复选框。2)、不选择数据库支持。3)、不选中“ActiveX 控件”复选框。4)、不选中“隐藏工具栏”和“打印和打印预览”复选框,选择Windows Sockets复选框。5)、默认。6)、设置CView类为CEditView,单击“完成”按钮,应用程序聊天工具就创建完成了。(3)、插入一个对话框IDD_DIALOG_CHANNEL,编辑各个控件的属性如下(用该资源创建对话框类CChannelDlg):资源标识标题相关属性/事件IDD_STATIC聊天频道IDC_EDIT_CHANNELCString m_channelIDCANCEL取消IDOK确定IDD_DIALOG_CHANNEL设置CChannelDlg(4)、打开菜单编辑器菜单IDR_MAINFRAME,设置菜单命令如下:资源标识标题命令处理函数ID_FILE_START启动服务(&S)tCtral+SCMyDoc:OnFileStart三、程序代码1、CChanneiDlg类的定义和实现部分1)头文件ChannelDlg.h,定义CChanneiDlg的基类CDialog。class CChannelDlg : public CDialogpublic:CChannelDlg(CWnd* pParent = NULL); / standard constructor enumIDD=IDD_DIALOG_CHANNEL;CString m_channel;protected:virtual void DoDataExchange(CDataExchange* pDX); /DDX DDV supportprotected:DECLARE_MESSAGE_MAP();2、在ChannelDlg.cpp中,类的CChannelDlg的实现部分。在这里主要定义CChannelDlg的构造函数,初始化聊天频道。/CChannelDlg的构造函数CChannelDlg:CChannelDlg(CWnd* pParent /*=NULL*/): CDialog(CChannelDlg:IDD, pParent)/AFX_DATA_INIT(CChannelDlg)m_channel = _T(1);/AFX_DATA_INIT2、类CListenSocket的定义和实现。1)头文件ListenSocket.h,定义类CSocket的派生类CListenSocket。class CMyDoc;class CListenSocket:public CSocketpublic:CListenSocket(CMyDoc* pDoc);virtual CListenSocket();public:virtual void OnAccept(int nErrorCode);protected:private:/于该套接字相对应的文档类CMyDoc* m_pDoc;2)ListenSocket.cpp, CListenSocket的实现部分,主要用来监控这些链接的状态,在客户主动离开或发生故障时从列表中删除相应表项,并及时更新连接表。#include stdafx.h#include 聊天工具.h#include ListenSocket.h#include 聊天工具Doc.h/CListenSocket 构造函数CListenSocket:CListenSocket(CMyDoc* pDoc)/保存指向文档类的指针m_pDoc=pDoc;/相应连接请求void CListenSocket:OnAccept(int nErrorCode)/首先调用基类函数CSocket:OnAccept(nErrorCode);/确保文档类指针有效ASSERT(m_pDoc);/通知相应的文档类有连接请求m_pDoc-AcceptClient();3、CClientSocket类的定义和实现部分1)、头文件Clientsocket.h,定义CSocket的派生类CClientSocket。class CMyDoc;class CClientSocket:public CSocketpublic:CClientSocket(CMyDoc* pDoc);virtual CClientSocket();public:virtual void OnReceive(int nErrorCode);protected:private: CMyDoc* m_pDoc;2)ClientSocket.cpp文件,CClientSocke的实现部分。#include stdafx.h#include 聊天工具.h#include ClientSocket.h#include 聊天工具Doc.h/CClientSocket 构造函数CClientSocket:CClientSocket(CMyDoc* pDoc)/保存对应的文档类指针m_pDoc=pDoc;/响应信息到达事件void CClientSocket:OnReceive(int nErrorCode)CSocket:OnReceive(nErrorCode);m_pDoc-ReadMessage(this);4、CMainFrame类的定义和实现部分1)CMainFrame类的接口,在头文件MainFrm.h中,定义类CFrameWnd的基类CMainFrame.class CMainFrame : public CFrameWndprotected: / create from serialization onlyCMainFrame();DECLARE_DYNCREATE(CMainFrame)virtual BOOL PreCreateWindow(CREATESTRUCT& cs);/ Implementationpublic:virtual CMainFrame();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endifprotected: / control bar embedded membersCStatusBar m_wndStatusBar;protected:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);DECLARE_MESSAGE_MAP();5、类C聊天工具Doc的定义和实现。1)定义文档类的头文件MyDoc.h,定义类C聊天工具Doc的接口。/添加如下文件包含语句#include ListenSocket.h#include ClientSocket.h/发送缓冲区最大长度#define MAX_BUFFER_SIZE 100/聊天频道偏移#define BASE_CHANNEL 2000class CMyDoc : public CDocumentprotected: / create from serialization onlyCMyDoc();DECLARE_DYNCREATE(CMyDoc)public:virtual BOOL OnNewDocument();virtual void Serialize(CArchive& ar);public:/从客服套接字中读取信息void ReadMessage(CClientSocket* socket);/从侦听套接字中接受客户连接请求void AcceptClient();virtual CMyDoc();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endifprotected:afx_msg void OnFileStart();DECLARE_MESSAGE_MAP()private:/向客户套接字发送信息void SendMessage(CClientSocket* socket,char* buffer);/显示从客户套接字中接收到的信息void ShowMessage(CClientSocket* socket,char* buffer);/客户套接字列表CPtrList m_list;/客户套接字CClientSocket* m_clientSocket;/侦听套接字CListenSocket* m_listenSocket;2)聊天工具Doc.cpp文件,C聊天工具Doc类的实现部分。#include stdafx.h#include 聊天工具.h#include 聊天工具Doc.h#include 聊天工具View.h#include ChannelDlg.h/构造函数CMyDoc:CMyDoc()/ TODO: add one-time construction code herem_clientSocket=NULL;m_listenSocket=NULL;/析构函数CMyDoc:CMyDoc()/关闭所有的客户套接字POSITION pos=m_list.GetHeadPosition();while (pos!=NULL)CClientSocket* client=(CClientSocket*)m_list.GetNext(pos);delete client;/关闭侦听套接字if (m_listenSocket!=NULL)m_listenSocket-Close();delete m_listenSocket;BOOL CMyDoc:OnNewDocument()if (!CDocument:OnNewDocument()return FALSE;(CEditView*)m_viewList.GetHead()-SetWindowText(NULL);return TRUE;void CMyDoc:Serialize(CArchive& ar)/ CEditView contains an edit control which handles all serialization(CEditView*)m_viewList.GetHead()-SerializeRaw(ar);void CMyDoc:AssertValid() constCDocument:AssertValid();void CMyDoc:Dump(CDumpContext& dc) constCDocument:Dump(dc);/“启动服务”菜单命令响应函数void CMyDoc: OnFileStart()/服务器频道选择对话框CChannelDlg dlg;if (dlg.DoModal()!=IDOK) return;/如果此前已经有一个侦听套接字,则先把他关闭if (m_listenSocket!=NULL)m_listenSocket-Close();delete m_listenSocket;/创建一个新的侦听套接字m_listenSocket=new CListenSocket(this);/根据用户选择的服务器频道设置套接字端口/端口号服务器频道加上频道偏移 BASE_CHANNELif (!m_listenSocket-Create(atoi(dlg.m_channel)+BASE_CHANNEL)AFxMessageBox(创建Socket失败!);m_listenSocket=NULL;return;/启动侦听套接字侦听连接if (!m_listenSocket-Listen()AFxMessageBox(Socket侦听异常!);delete m_listenSocket;m_listenSocket=NULL;return;/删除列表中所有客户套接字POSITION pos=m_list.GetHeadPosition();while (pos!=NULL)CClientSocket* client=(CClientSocket*)m_list.GetNext(pos);delete client;/AcceptClient:接收一个客户的套接字/ 参数:无/ 返回值:无void CMyDoc: AcceptClient()/创建一个新的客户套接字m_clientSocket=new CClientSocket(this);/用这个新的套接字从侦听套接字中接收请求if(!m_listenSocket-Accept(*m_clientSocket)AFxMessageBox(Socket接收出现异常!);delete m_clientSocket;m_clientSocket=NULL;return;#ifdef _DEBUG/在正式发行版本中不弹出对话框/如果不及时关闭对话框,就会丢失部分客户连接AFxMessageBox(有用户加入!);#endif /将新创建的客户套接字添加到列表中m_list.AddTail(m_clientSocket);/Readmessage:从一个客户端接字/ 参数:无/ 返回值:无void CMyDoc: ReadMessage(CClientSocket *socket)/接受信息缓存区char bufferMAX_BUFFER_SIZE;/检查接收到的信息长度是否有效int len=socket-Receive(buffer,MAX_BUFFER_SIZE-1);/检查接收到的信息长度是否有效if (lenGetEditCtrl();/获取与该客户套接字对应的对方套接字的名称CString addr;UINT port;socket-GetPeerName(addr,port);/格式化显示信息char msgMAX_BUFFER_SIZE;wsprintf(msg,%d%s:%srn,port,addr,buffer);/将显示信息添加到编辑控件的末尾int len=eView-GetWindowTextLength();edit.SetSel(len,len);edit.ReplaceSel(msg);/SendMessage:向其他客户套接字转发接收到的信息/参数:socket:接受到客户信息的套接字/参数:buffer:信息缓冲区/返回值:无void CMyDoc:SendMessage(CClientSocket *socket,char* buffer)/以此获取列表中的客户套接字POSITION pos=m_list.GetHeadPosition();while(pos!=NULL)CClientSocket* client=(CClientSocket*)m_list.GetNext(pos);/不向接收到的信息的套接字发送本信息if(client=socket) continue;/通知客户套接字发送信息client-Send(buffer,strlen(buffer);6、C聊天工具View的定义,定义CEditView派生类CC聊天工具View的类定义。class CMyView : public CEditViewprotected: / create from serialization onlyCMyView();DECLARE_DYNCREATE(CMyView)public:CMyDoc* GetDocument();public:public:virtual void OnDraw(CDC* pDC); / overridden to draw this viewvirtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected:public:virtual CMyView();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endifprotected:DECLARE_MESSAGE_MAP();四、总结在这个服务器端聊天程序中,聊天服务器能够检和显示所有聊天用户的聊天内容,以及各个聊天客户的网络地址和连接端口。对于正规的聊天程序来说,每个聊天客户还会有自身的详细信息,如:昵称,编号,身份,个人简历等。所有这些功能的实现都是很简单的,可以通过服务器的数据库来保存这些用户的信息,然后给每个用户一个唯一的编号,在每条信息头部加上发送人的编号,对方客户再通过服务器数据库就能获取聊天对象的详细信息。第二部分 客户端聊天程序一、程序设计思想相应的客户端必须要能够与服务器端相互匹配才能进行通信。客户段聊天程序需要完成以下功能:1)客户端聊天程序要负责建立和维护与服务器的链接,通过获取用户的设置尝试与服务器的链接,并且随时检测连接的状态。2)客户端聊天程序要把用户输入的信息及时的发送到聊天服务器。一般情况下,当用户输入一行信息并且按下回车键之后,聊天程序就要把这一行信息发送出去,才能及时的满足用户的交互需求。3)客户端聊天程序要随之准备好来自服务器的信息,随时把接收到的信息显示出来,让用户及时看到对方的响应。4)在用户退出聊天程序时要关闭与服务器的链接。比较好的做法是提前通知服务器,或者直接给服务器发送一条退出通知,使得服务器能够及时掌握客户端的连接状态,把对方客户的退出信息及时发送到对等实体上。客户端聊天程序需要使用一个通过CSocket类派生出来的CChatSocket类来实现。该套接字用来发送一个与服务器的连接请求和维护与服务器的链接,发送和接收聊天信息,完成上述各种功能。二、程序设计框架和步骤(1)、用MFC AppWizard(exe)创建一个新工程,命名为客户端。(2)、在MFC AppWizard中按照下述步骤设置工程属性:1)、设置应用程序类型为单文档模式,选择“文档/查看体系结构支持”复选框。2)、不选择数据库支持。3)、不选中“ActiveX 控件”复选框。4)、不选中“隐藏工具栏”和“打印和打印预览”复选框,选择Windows Sockets复选框。5)、默认。6)、设置CView类为CEditView,单击“完成”按钮,应用程序客户端就创建完成了。(3)、插入一个对话框IDD_DIALOG_SETUP,编辑各个控件的属性如下(用该资源创建对话框类CSetupDlg):资源标识标题相关属性/事件IDD_STATIC聊天服务器地址IDC_EDIT_ADDRESSCString m_addressIDC_STATIC聊天频道IDC_EDIT_CHANNELInt m_portIDOK确定IDCANCEL取消IDD_DIALOG_SETUP设置CSetupDlg(4)、打开菜单编辑器菜单IDR_MAINFRAME,设置菜单命令如下:资源标识标题命令处理函数ID_FILE_CONNECT连接服务器(&C)tCtral+CCMyDoc:OnFileConnect三、程序代码1、CSetupDlg类的定义和实现。1)在SetupDlg.h头文件中定义类CSetupDlg。#pragma onceclass CSetupDlg : public CDialogpublic:CSetupDlg(CWnd* pParent=NULL);enum IDD=IDD_DIALOG_SETUP;CString m_address;int m_port;protected:virtual void DoDataExchange(CDataExchange* pDX);protected:DECLARE_MESSAGE_MAP();2)SetupDlg.cpp文件,实现CSetupDlg.类#include stdafx.h#include 客户端.h#include SetupDlg.h/CSetupDlg 构造函数CSetupDlg:CSetupDlg(CWnd* pParent /*=NULL*/) : CDialog(CSetupDlg:IDD,pParent)m_address=_T();/初始化聊天频道m_port=1;void CSetupDlg:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);DDX_Text(pDX,IDC_EDIT_ADDRESS,m_address);DDX_Text(pDX,IDC_EDIT_CHANNEL,m_port);2、CChatSocket类的定义和实现1)CChatSocket通过头文件ChatSocketh类定义#pragma once/提前声明文档类class CMyDoc;class CChatSocket : public CSocketpublic:CChatSocket(CMyDoc* pDoc);virtual CChatSocket();public:/数据到达响应函数virtual void OnReceive(int nErrorCode);protected:private:/添加一个新成员,并使其指向相应的文档类CMyDoc* m_pDoc;2)ChatSocket.cpp文件,CChatSocket类的实现部分#include stdafx.h#include 客户端.h#include ChatSocket.h#include 客户端Doc.h/CChatSocket 构造函数CChatSocket:CChatSocket(CMyDoc* pDoc)/保存文档类指针 m_pDoc=pDoc;/相应数据到达信号void CChatSocket:OnReceive(int nErrorCode)/先调用基类函数进行处理CSocket:OnReceive(nErrorCode);/通知文档类接收数据m_pDoc-ReceiveMessage();CChatSocket:CChatSocket()3、MainFrame类的定义和实现1)MainFrame类的定义,通过头文件MainFrm.h定义类的接口。class CMainFrame : public CFrameWndprotected: / create from serialization onlyCMainFrame();DECLARE_DYNCREATE(CMainFrame)public:public:virtual BOOL PreCreateWindow(CREATESTRUCT& cs);protected:virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs,CCreateContext* pContext);public:virtual CMainFrame();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endifprotected: / control bar embedded membersCStatusBar m_wndStatusBar;protected:afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);DECLARE_MESSAGE_MAP()private:/添加一个窗口分隔栏CSplitterWnd m_splitter;#endif 2)MainFrm.cpp文件,CMainFrm类的实现部分。#include stdafx.h#include 客户端.h#include MainFrm.h#include 客户端Doc.h#include 客户端View.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endifIMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)/消息响应定义ON_WM_CREATE()END_MESSAGE_MAP()/响应子窗口创建消息/用一个分割栏创建两个分割窗体BOOL CMainFrame:OnCreateClient(LPCREATESTRUCT lpcs,CCreateContext* pContext)/创建一个两行一列的静态分割栏if (!m_splitter.CreateStatic(this,2,1)return FALSE;/获取客户窗口大小CRect rect;GetClientRect(&rect);/设置第一个分割窗口大小CSize size=rect.Size();size.cy -=150;/以CEditView为基础创建第一个分割窗体if(!m_splitter.CreateView(0,0,RUNTIME_CLASS(CEditView),size,pContext)return FALSE;/以C客户端View为基础创建第二个分割窗体if (!m_splitter.CreateView(1,0,RUNTIME_CLASS(CMyView),CSize(0,0),pContext) return FALSE;/将第二个窗口设置为激活窗口m_splitter.SetActivePane(1,0,(CView*)m_splitter.GetPane(1,0);return FALSE;static UINT indicators =ID_SEPARATOR, / status line indicatorID_INDICATOR_CAPS,ID_INDICATOR_NUM,ID_INDICATOR_SCRL,;CMainFrame:CMainFrame()/ TODO: add member initialization code hereCMainFrame:CMainFrame()int CMainFrame:OnCreate(LPCREATESTRUCT lpCreateStruct)if (CFrameWnd:OnCreate(lpCreateStruct) = -1)return -1;if (!m_wndStatusBar.Create(this) |!m_wndStatusBar.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT)TRACE0(Failed to create status barn);return -1; / fail to createreturn 0;BOOL CMainFrame:PreCreateWindow(CREATESTRUCT& cs)if( !CFrameWnd:PreCreateWindow(cs) )return FALSE;return TRUE;#ifdef _DEBUGvoid CMainFrame:AssertValid() constCFrameWnd:AssertValid();void CMainFrame:Dump(CDumpContext& dc) constCFrameWnd:Dump(dc);#endif /_DEBUG4、C客户端Doc类的定义与实现部分1)在头文件MyDoc.h中定义C客户端Doc类,定义C客户端Doc类的接口。#include ChatSocket.h/定义发送缓冲区的最大长度#define MAX_BUFFER_SIZE 100/定义聊天频道偏移#define BASE_CHANNEL 2000#if !defined(AFX_DOC_H_05851AB0_9BA8_4964_BAF9_6D6F1EFA4E33_INCLUDED_)#define AFX_DOC_H_05851AB0_9BA8_4964_BAF9_6D6F1EFA4E33_INCLUDED_#if _MSC_VER 1000#pragma once#endif / _MSC_VER 1000class CMyDoc : public CDocumentprotected: / create from serialization onlyCMyDoc();DECLARE_DYNCREATE(CMyDoc)public: public:public:virtual BOOL OnNewDocument();virtual void Serialize(CArchive& ar);public:/发送聊天内容void SendMessage(LPSTR msg);/接收数据void ReceiveMessage(void);virtual CMyDoc();#ifdef _DEBUGvirtual void AssertValid() const;virtual void Dump(CDumpContext& dc) const;#endifprotected:protected:/相应菜单命令afx_msg void OnFileConnect();DECLARE_MESSAGE_MAP()private:/在视图中显示信息void ShowMessage(LPSTR msg);/连接套接字CChatSocket* m_socket;#endif 2)客户端Doc.cpp文件中,CMyDoc类的实现部分。#include stdafx.h#include 客户端.h#include SetupDlg.h#include 客户端View.h#include 客户端Doc.h#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE = _FILE_;#endifIMPLEMENT_DYNCREATE(CMyDoc, CDocument)/消息映射BEGIN_MESSAGE_MAP(CMyDoc, CDocument)ON_COMMAND(ID_FILE_CONNECT, OnFileConnect)END_MESSAGE_MAP()/C客户端Doc 构造函数CMyDoc:CMyDoc() /将套接字设置为空m_socket=NULL;CMyDoc:CMyDoc()BOOL CMyDoc:OnNewDocument()if (!CDocument:OnNewDocument()return FALSE;(CEditView*)m_viewList.GetHead()-SetWindowText(NULL);return TRUE;void CMyDoc:Serialize(CArchive& ar)(CEditView*)m_viewList.GetHead()-SerializeRaw(ar);#ifdef _DEBUGvoid CMyDoc:AssertValid() constCDocument:AssertValid();void CMyDoc:Dump(CDumpContext& dc) constCDocument:Dump(dc);#endif /_DEBUG/相应服务器连接命令void CMyDoc:OnFileConnect() /显示连接设置对话框CSetupDlg dlg;if (dlg.DoModal()!=IDOK) return;/先关闭上次的有效连接if(m_socket!=NULL)m_socket-Close();delete m_socket;/创建一个新的套接字m_socket=new CChatSocket(this);if(!m_socket-Create()AfxMessageBox(创建socket失败!);delete m_socket;m_socket=NULL;return;/连接服务器if(!m_socket-Connect(dlg.m_address,dlg.m_port+BASE_CHANNEL)AfxMessageBox(连接服务器失败!);delete m_socket;m_socket=NULL;return;/显示连接成功信息AfxMessageBox(成功连接到聊天服务器!);/ReceiveMessage:接收服务器发送的数据/ 参数:无/ 返回值:无void

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论