MFC的網(wǎng)絡(luò)編程_第1頁(yè)
MFC的網(wǎng)絡(luò)編程_第2頁(yè)
MFC的網(wǎng)絡(luò)編程_第3頁(yè)
MFC的網(wǎng)絡(luò)編程_第4頁(yè)
MFC的網(wǎng)絡(luò)編程_第5頁(yè)
已閱讀5頁(yè),還剩16頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、MFC的網(wǎng)絡(luò)編程今天來(lái)八一八,MFC的SOCKET 編程,利用CSocket實(shí)現(xiàn)一個(gè)基于TCP實(shí)現(xiàn)一個(gè)QQ聊天程序。你會(huì)發(fā)現(xiàn),MFC要比WIN32 簡(jiǎn)單的多。但是如果你不理解具體API socket基礎(chǔ)知識(shí),你可能會(huì)覺(jué)得有一點(diǎn)費(fèi)解。 所以在開(kāi)始之前 我還是請(qǐng)大家先看看   在應(yīng)用程序開(kāi)始的時(shí)候,我們先應(yīng)該初始話winSock 庫(kù),所以便會(huì)用到下面的一個(gè)函數(shù)。cpp view plain copy1. BOOL AfxSocketInit( WSADATA* lpwsaData = NULL );

2、 /用來(lái)初始化Socket,用WSAStartup();來(lái)初始化,在應(yīng)用程序結(jié)束時(shí)他會(huì)自動(dòng)調(diào)用WSACleanup()  我們?cè)陂_(kāi)始編程之前,應(yīng)該調(diào)用這個(gè)函數(shù),對(duì)Socket進(jìn)行初始化。如果初始化成功返回非0 ,否則返回0.可能人會(huì)問(wèn),這個(gè)函數(shù)加載的是那個(gè)版本的Socket庫(kù)呢?通過(guò)查看底層代碼,我們發(fā)現(xiàn),他加載的是1.1版本的Socket注意:這個(gè)函數(shù)只能在你自己應(yīng)用程序的 CXXWinApp:InitInstance 中初始化.在初始化前還要記得加入頭文件Afxsock.h我服務(wù)器端程序 為  NetChatServer 

3、0;所以我在的CNetChatServerApp:InitInstance()中加入/CNetChatServerApp:InitInstance()/cpp view plain copy1.   if(!AfxSocketInit()  2.   3.     AfxMessageBox(_T("Socket 庫(kù)初始化出錯(cuò)!");  4.     return false;

4、  5.   m_iSocket 是一個(gè) CServerSocket*的 指針  ,CServerSocket類是一個(gè)我們自己的類我會(huì)在后面給出相應(yīng)代碼,他繼承于CSocket類。cpp view plain copy1.   m_iSocket = new CServerSocket(); / 1.動(dòng)態(tài)創(chuàng)建一個(gè)服務(wù)器Socket對(duì)象。  2.     if(!m_iSocket) &#

5、160;3.       4. AfxMessageBox(_T("動(dòng)態(tài)創(chuàng)建服務(wù)器套接字出錯(cuò)!");  5. return false;  6.       接著創(chuàng)建套接字cpp view plain copy1. if(!m_iSocket->Create(8989)  2.   3.     Afx

6、MessageBox(_T("創(chuàng)建套接字錯(cuò)誤!");  4.     m_iSocket->Close();  5.     return false;  6.   其中8989 是指定的端口號(hào),但是要注意在保存我們指定的8989端口前,這個(gè)端口是空閑的沒(méi)有被其他進(jìn)程所占用,那怎么查看端口是否被其他進(jìn)程占用呢?首先打開(kāi)cmd 鍵入 netstat -aon 你會(huì)看到所有的TCP/UDP 信息

7、 ,但是由于太多了不好查看,所以。我們?cè)僭谧钕旅?tasklist|find “8989”現(xiàn)在我們看到 我們沒(méi)有找到任何 和8989端口相關(guān)的東西,所以說(shuō)明8989端口沒(méi)有被占用。創(chuàng)建了套接字以后按照win32的步驟我們就應(yīng)該 對(duì)bind端口。但是MFC 不這樣,應(yīng)為MFC的Create內(nèi)部已經(jīng)調(diào)用了bind ,如下是MFC的底層代碼cpp view plain copy1. BOOL CAsyncSocket:Create(UINT nSocketPort, int nSocketType,long lEvent,

8、0;LPCTSTR lpszSocketAddress)  2.   3.       if (Socket(nSocketType, lEvent)  4.         5.           if (Bind(nSocketPort,lpszSock

9、etAddress)/調(diào)用了bind  6.                   return TRUE;  7.           int nResult = GetLastError();  8.  &#

10、160;        Close();  9.           WSASetLastError(nResult);  10.         11.       return FALSE;  12. &#

11、160; 所以 我們不用在調(diào)用bind 了,直接對(duì)套接字進(jìn)行監(jiān)聽(tīng)cpp view plain copy1. if(!m_iSocket->Listen()  2.   3.     AfxMessageBox(_T("監(jiān)聽(tīng)失?。?quot;);  4.     m_iSocket->Close();  5.     return fal

12、se;  6.   /然后重載ExitInstance,退出時(shí)對(duì)進(jìn)行清理cpp view plain copy1. int CNetChatServerApp:ExitInstance()  2.   3. if(m_iSocket)  4.   5. delete m_iSocket;  6. m_iSocket = NULL;  7.   8. retu

13、rn CWinApp:ExitInstance();  9.   /下面 來(lái)看下CServerSocket的具體實(shí)現(xiàn)cpp view plain copy1. #pragma once  2.   3. #include "ClientSocket.h"  4.   5. class CServerSocket : public CSocket  

14、6.   7. public:  8.     CServerSocket();  9.     virtual CServerSocket();  10. public :   11.     CPtrList m_listSockets;/用來(lái)保存服務(wù)器與所有客戶端連接成功后的ClientSocket  12. &

15、#160; 13.   14. public :   15.     virtual void OnAccept(int nErrorCode);  16. ;  cpp view plain copy1. #include "stdafx.h"  2. #include "NetChatServer.h" 

16、 3. #include "ServerSocket.h"  4.   5. CServerSocket:CServerSocket()  6.   7.   8.   9.   10. CServerSocket:CServerSocket()  11.   12.   13.   14.   15. void

17、60;CServerSocket:OnAccept(int nErrorCode)  16.   17.     /接受到一個(gè)連接請(qǐng)求  18.     CClientSocket* theClientSock(0);  19.     theClientSock = new CClientSocket(&m_listSockets);&#

18、160; 20.     if(!theClientSock)  21.       22.         AfxMessageBox(_T("內(nèi)存不足,客戶連接服務(wù)器失??!");  23.         return;  24.  &

19、#160;    25.     Accept(*theClientSock);  26.     /加入list中便于管理  27.     m_listSockets.AddTail(theClientSock);  28.     CSocket:OnAccept(nErrorCode);  29.  

20、 我們可以看到在CServerSocket中 又出現(xiàn)了一個(gè)CClientSocket的類,這個(gè)類和CServerSocket一樣,也是派生于CSocket類,但是專門用于客戶端的Socket。在這里必須重載OnAccept(int nErrorCode)函數(shù),這樣CServerSocket才能接收到客戶端的請(qǐng)求,并且必須在OnAccept中調(diào)用Accept()函數(shù)對(duì)連接請(qǐng)求進(jìn)行響應(yīng)。在OnAccept()我們用一個(gè)List 將ClientSocket指針保存,以便以后調(diào)用訪問(wèn)。/接著 我們?cè)賮?lái)看看CClientSocket類cpp view plain copy1

21、. #pragma once  2.   3. #include "stdafx.h"  4. /  5. /說(shuō)明,該類用于和客戶端建立通信的Socket  6. /  7.   8. class CClientSocket : public CSocket  9.   10. public:  11.  &

22、#160;  CClientSocket(CPtrList* pList);  12.     virtual CClientSocket();  13. public:  14.     CPtrList* m_pList;/保存服務(wù)器ClientSocket中List的東西,這個(gè)是中CServerSocket中傳過(guò)來(lái)的  15.     CSt

23、ring m_strName; /連接名稱  16. public:  17.     virtual void OnClose(int nErrorCode);   18.     virtual void OnReceive(int nErrorCode);  19.     void OnLo

24、goIN(char* buff,int nlen);/處理登錄消息  20.     void OnMSGTranslate(char* buff,int nlen);/轉(zhuǎn)發(fā)消息給其他聊天群  21.     CString UpdateServerLog();/服務(wù)器端更新、記錄日志  22.     void UpdateAllUser(CSt

25、ring strUserInfo);/更新服務(wù)器端的在線人員列表  23. private:  24.     BOOL WChar2MByte(LPCWSTR srcBuff, LPSTR destBuff, int nlen);/多字節(jié)的轉(zhuǎn)換  25. ;  可以看到 我們重載了OnClose()、OnReceive()函數(shù),這樣當(dāng)套接字關(guān)閉、有數(shù)據(jù)到達(dá)時(shí),就會(huì)自動(dòng)調(diào)用這兩個(gè)函數(shù),我們便可以在這兩個(gè)函數(shù)

26、中響應(yīng)、處理事件。由于本人使用的是VS2010,并且采用的Unicode編碼,所以,經(jīng)常要涉及Unicode轉(zhuǎn)多字節(jié)的情況,于是就寫了WChar2MByte()進(jìn)行轉(zhuǎn)換cpp view plain copy1. #include "stdafx.h"  2. #include "NetChatServer.h"  3. #include "ClientSocket.h"  4. #include "Head

27、er.h"  5. #include "NetChatServerDlg.h"  6.   7. CClientSocket:CClientSocket(CPtrList* pList)  8.     :m_pList(pList),m_strName(_T("")  9.   10.   11.   12.  &#

28、160;13. CClientSocket:CClientSocket()  14.   15.   16.   17. /  18.  void CClientSocket:OnReceive(int nErrorCode)  19.    20.      /有消息接收  21.      /先

29、得到信息頭  22.      HEADER head;  23.      int nlen = sizeof HEADER;  24.      char *pHead = NULL;  25.      pHead =

30、60;new charnlen;  26.      if(!pHead)  27.        28.          TRACE0("CClientSocket:OnReceive 內(nèi)存不足!");  29.       

31、   return;  30.        31.      memset(pHead,0, sizeof(char)*nlen );  32.      Receive(pHead,nlen);  33.      head.type = (LP

32、HEADER)pHead)->type;  34.      head.nContentLen = (LPHEADER)pHead)->nContentLen;  35.      delete pHead;  36.      pHead = NULL;  37.   38. 

33、0;    /再次接收,這次是數(shù)據(jù)類容  39.      pHead = new charhead.nContentLen;  40.      if(!pHead)  41.        42.         &

34、#160;TRACE0("CClientSocket:OnRecive 內(nèi)存不足!");  43.          return;  44.        45.     if( Receive(pHead, head.nContentLen)!=head.nContentLen)  4

35、6.       47.         AfxMessageBox(_T("接收數(shù)據(jù)有誤!");  48.         delete pHead;  49.         return;  50. &#

36、160;     51.      /根據(jù)消息類型,處理數(shù)據(jù)/  52.      switch(head.type)  53.        54.      case MSG_LOGOIN:   55.    

37、60;     OnLogoIN(pHead, head.nContentLen);  56.          break;  57.      case MSG_SEND:   58.          OnMSGTransl

38、ate(pHead, head.nContentLen);  59.          break;  60.      default : break;  61.        62.   63.      delete

39、0;pHead;  64.      CSocket:OnReceive(nErrorCode);  65.    66.   67.  /關(guān)閉連接  68.  void CClientSocket:OnClose(int nErrorCode)  69.    70.       CTi

40、me time;   71.      time = CTime:GetCurrentTime();  72.      CString strTime = time.Format("%Y-%m-%d  %H:%M:%S  ");  73.      strT

41、ime = strTime + this->m_strName + _T("  離開(kāi).rn");  74.      (CNetChatServerDlg*)theApp.GetMainWnd()->DisplayLog(strTime);  75.      m_pList->RemoveAt(m_pList->Find(this)

42、;  76.      /更改服務(wù)器在線名單  77.      CString str1 = this->UpdateServerLog();  78.      /通知客戶端刷新在線名單  79.      this->UpdateAllUser(str1); &

43、#160;80.      this->Close();  81.      /銷毀該套接字  82.      delete this;  83.     CSocket:OnClose(nErrorCode);  84.    85.   86.  

44、/登錄  87.  void CClientSocket:OnLogoIN(char* buff, int nlen)  88.    89.      /對(duì)得接收到的用戶信息進(jìn)行驗(yàn)證  90.      /. (為了簡(jiǎn)化這步省略)  91.      /登錄成功 &#

45、160;92.      CTime time;   93.      time = CTime:GetCurrentTime();  94.      CString strTime = time.Format("%Y-%m-%d %H:%M:%S  ");  95.

46、   96.      CString strTemp(buff);  97.      strTime = strTime + strTemp + _T("  登錄.rn");  98.     /記錄日志  99.     &

47、#160;(CNetChatServerDlg*)theApp.GetMainWnd()->DisplayLog(strTime);  100.      m_strName = strTemp;  101.      /更新服務(wù)列表  102.      CString str1 = this->UpdateServerLo

48、g();  103.      /更新在線所有客服端  104.      this->UpdateAllUser(str1);  105.    106.   107. /轉(zhuǎn)發(fā)消息  108.  void CClientSocket:OnMSGTranslate(char* buff, int nlen)

49、60; 109.    110.      HEADER head;  111.      head.type = MSG_SEND;  112.      head.nContentLen = nlen;  113.      POSITION&#

50、160;ps = m_pList->GetHeadPosition();  114.   115.      while(ps!=NULL)  116.        117.         CClientSocket* pTemp = (CClientSocket*)m_pLis

51、t->GetNext(ps);  118.         pTemp->Send(&head,sizeof(HEADER);  119.         pTemp->Send(buff, nlen);  120.        121.   

52、0;122.   123.   124.  BOOL CClientSocket:WChar2MByte(LPCWSTR srcBuff, LPSTR destBuff, int nlen)  125.    126.      int n = 0;  127.      n =

53、 WideCharToMultiByte(CP_OEMCP,0, srcBuff, -1, destBuff,0, 0, FALSE );  128.      if(n<nlen)  129.         return FALSE;  130.   131.    &

54、#160; WideCharToMultiByte(CP_OEMCP, 0, srcBuff, -1, destBuff, nlen, 0, FALSE);  132.   133.      return TRUE;  134.    135.   136.  /跟新所有在線用戶  137.  void&#

55、160;CClientSocket:UpdateAllUser(CString strUserInfo)  138.    139.       HEADER _head;  140.      _head.type = MSG_UPDATE;  141.      _head.nContentLen

56、0;= strUserInfo.GetLength()+1;  142.      char *pSend = new char_head.nContentLen;  143.      memset(pSend, 0, _head.nContentLen*sizeof(char);  144.     if( !WC

57、har2MByte(strUserInfo.GetBuffer(0), pSend, _head.nContentLen)  145.       146.         AfxMessageBox(_T("字符轉(zhuǎn)換失敗");  147.         delete pSend;

58、60; 148.         return;  149.       150.     POSITION ps = m_pList->GetHeadPosition();  151.     while(ps!=NULL)  152.    

59、;   153.          CClientSocket* pTemp = (CClientSocket*)m_pList->GetNext(ps);  154.          /發(fā)送協(xié)議頭  155.         &#

60、160;pTemp->Send(char*)&_head, sizeof(_head);  156.          pTemp->Send(pSend,_head.nContentLen );  157.          158.        159. 

61、0;   delete pSend;  160.    161.    162.   163.  /跟新服務(wù)器在線名單    164.  / 返回在線用戶列表的String  165. CString CClientSocket:UpdateServerLog()  166.    167.  &#

62、160;   CString strUserInfo = _T("");  168.        169.      POSITION ps = m_pList->GetHeadPosition();  170.   171.      while(p

63、s!=NULL)  172.        173.          CClientSocket* pTemp = (CClientSocket*)m_pList->GetNext(ps);  174.          strUserInfo += 

64、pTemp->m_strName + _T("#");  175.        176.     (CNetChatServerDlg*)theApp.GetMainWnd()->UpdateUserInfo(strUserInfo);  177.   178.     return strUserInfo; &#

65、160;179.    /在上面的代碼中 還涉及到一個(gè)HEADER struct 這是一個(gè)我們自定義的一個(gè)頭結(jié)構(gòu),相當(dāng)于自定義的一個(gè)協(xié)議,不過(guò)這個(gè)很簡(jiǎn)化。在這個(gè)協(xié)議里我們要指定我們本次要發(fā)送數(shù)據(jù)的type,既是我們發(fā)送的那種消息的數(shù)據(jù)。還有數(shù)據(jù)的長(zhǎng)度。為了不浪費(fèi)空間,我們選擇2次發(fā)送。每次給服務(wù)器發(fā)數(shù)據(jù)時(shí)都 先發(fā)送一個(gè)協(xié)議頭,然后再發(fā)送數(shù)據(jù)本身。其實(shí)也可以既不浪費(fèi)空間,也只發(fā)送一次。但是那就在發(fā)送之前,對(duì)數(shù)據(jù)進(jìn)行序列化。在接收端接收到數(shù)據(jù)后又反序列化。但是C+中并沒(méi)有提供相應(yīng)的方法,所以我們要么自己寫,要么用第三方的庫(kù)類。但是這種方法代價(jià)比,我們分兩次發(fā)送代價(jià)高得

66、多,所以為了方便我們就分2次發(fā)送。/定義協(xié)議頭 因?yàn)橹苯右獋鬏數(shù)念惾葜杏胁淮_定長(zhǎng)的的類容/為了避免浪費(fèi)空間選擇分兩部分傳輸,故定義一個(gè)頭/#pragma once/自定義協(xié)議/const int MSG_LOGOIN = 0x01; /登錄const int MSG_SEND = 0x11;   /發(fā)送消息const int MSG_CLOSE = 0x02;  /退出const int MSG_UPDATE = 0x21; /更新信息#pragma pack(push,1)typedef struct tagHeaderint type ;/協(xié)議類型int nConten

67、tLen; /將要發(fā)送內(nèi)容的長(zhǎng)度HEADER ,*LPHEADER;#pragma pack(pop)這里面涉及了一個(gè)字節(jié)對(duì)齊的知識(shí),請(qǐng)查看 /到這里基本服務(wù)器端基本有關(guān)發(fā)送的框架全部搭建完畢,剩下的就是一些界面編程,比如什么顯示之類的工作,在這里我就不貼這些代碼,但是呢我會(huì)在最后給出整個(gè)工程的下載地址,下面我們就簡(jiǎn)單看看客戶端的代碼/客戶端/客戶端相對(duì)來(lái)說(shuō)要簡(jiǎn)單的多,他只涉及一個(gè)CClientSocket,但是呢,這個(gè)類并不是和服務(wù)器端那個(gè)一樣的,只是名字相同而已。首先還是要初始化socket庫(kù) 不多說(shuō)。位置和添加方法和客戶端一樣、接著創(chuàng)建客戶端的套接字、然后連接服務(wù)器。 

68、;cpp view plain copy1. if(!AfxSocketInit()  2.       3.         AfxMessageBox(_T("初始化Socket庫(kù)失敗!");  4.         return false;  5.  

69、     6.   7.     m_pSocket = new CClientSocket();  8.     if(!m_pSocket)  9.       10.         AfxMessageBox(_T("內(nèi)存

70、不足!");  11.         return false;  12.       13.   14.     if(!m_pSocket->Create()  15.       16.      

71、;   AfxMessageBox(_T("創(chuàng)建套接字失敗!");  17.         return false;  18.       19.   20.     CLogoInDlg* pLogoinDlg;/登錄對(duì)話框  21.   &#

72、160; pLogoinDlg = new CLogoInDlg();  22.       23.     if(pLogoinDlg->DoModal()=IDOK)/這里其實(shí)是點(diǎn)擊了推出的按鈕,只是ID我用的是IDOK的,沒(méi)有修改  24.       25.        &

73、#160;/不登錄  26.         delete pLogoinDlg;  27.         m_pSocket->Close();  28.         return false;  29.    &#

74、160;  30.     else  31.       32.         delete pLogoinDlg;  33.       (上面還有一個(gè)CLogoInDlg類,那是一個(gè)登錄對(duì)話框的類,在后面會(huì)給出他的部分代碼。)接著和服務(wù)器端一樣,重載ExitInstance();c

75、pp view plain copy1. int CNetChatClientApp:ExitInstance()  2.   3.     if(m_pSocket)  4.       5.         delete m_pSocket;  6.    

76、0;    m_pSocket = NULL;  7.       8.   9.     return CWinApp:ExitInstance();  10.   11.   12. CClientSocket* CNetChatClientApp:GetMainSocket() const &

77、#160;13.   14.     return m_pSocket;  15.   /然后 看看客戶端的CClientSocket的實(shí)現(xiàn)cpp view plain copy1. #pragma once  2.   3. class CClientSocket : public CSocket  4.   5. public:

78、60; 6.     CClientSocket();  7.     virtual CClientSocket();  8. public:  9.     virtual void OnReceive(int nErrorCode);/客戶端接收消息  10.     BOOL SendMSG

79、(LPSTR lpBuff, int nlen);/客戶端發(fā)送消息  11.     BOOL LogoIn(LPSTR lpBuff, int nlen);/客戶端登錄  12.     CString m_strUserName;/用戶姓名  13. ;  顯然我們必須重載OnReceive函數(shù),來(lái)處理接收到的數(shù)據(jù),其他函數(shù)是一些事件處理函數(shù),和說(shuō)明一樣

80、cpp view plain copy1. #include "stdafx.h"  2. #include "NetChatClient.h"  3. #include "ClientSocket.h"  4. #include "Header.h"  5. #include "NetChatClientDlg.h"  6.

81、/ CClientSocket  7.   8. CClientSocket:CClientSocket()  9.     :m_strUserName(_T("")  10.   11.   12.   13.   14. CClientSocket:CClientSocket()  15.   16.  

82、0;17.   18.   19. void CClientSocket:OnReceive(int nErrorCode)  20.   21.     /首先接受head頭  22.     HEADER head   23.     char* pHead = NULL; 

83、 24.     pHead =  new charsizeof(head);  25.     memset(pHead, 0, sizeof(head);  26.     Receive(pHead, sizeof(head);  27.   28.     head.ty

84、pe =(LPHEADER)pHead)->type;  29.     head.nContentLen = (LPHEADER)pHead)->nContentLen;  30.     delete pHead;  31.     pHead = NULL;  32.   33.  

85、0;  char* pBuff = NULL;  34.     pBuff = new charhead.nContentLen;  35.     if(!pBuff)  36.       37.         AfxMessage

86、Box(_T("內(nèi)存不足!");  38.         return;  39.       40.     memset(pBuff, 0 , sizeof(char)*head.nContentLen);  41.     if(head.nContentLen

87、!=Receive(pBuff, head.nContentLen)  42.       43.         AfxMessageBox(_T("收到數(shù)據(jù)有誤!");  44.         delete pBuff;  45.    

88、60;    return;  46.       47.     CString strText(pBuff);  48.     switch(head.type)  49.       50.     case MSG_UPDATE:

89、   51.           52.             CString strText(pBuff);  53.             (CNetChatClientDlg*)(AfxGe

90、tApp()->GetMainWnd()->UpdateUserInfo(strText);  54.           55.         break;  56.     case MSG_SEND:  57.       

91、60;    58.             /顯示接收到的消息  59.             CString str(pBuff);  60.           

92、  (CNetChatClientDlg*)(AfxGetApp()->GetMainWnd()->UpdateText(str);  61.             break;  62.           63.     default: break;

93、  64.       65.   66.     delete pBuff;  67.     CSocket:OnReceive(nErrorCode);  68.   69.   70. BOOL CClientSocket:SendMSG(LPSTR lpBuff, int nle

94、n)  71.   72.     /生成協(xié)議頭  73.     HEADER head;  74.     head.type = MSG_SEND;  75.     head.nContentLen = nlen;  76.   77. &#

95、160;   if(Send(&head, sizeof(HEADER)=SOCKET_ERROR)  78.       79.         AfxMessageBox(_T("發(fā)送錯(cuò)誤!");  80.         return FALSE;  

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論