滑動窗口協議仿真_第1頁
滑動窗口協議仿真_第2頁
滑動窗口協議仿真_第3頁
滑動窗口協議仿真_第4頁
滑動窗口協議仿真_第5頁
已閱讀5頁,還剩24頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、滁州學院課程設計報告課程名稱: 計算機網絡 設計題目: 滑動窗口協議仿真 系 別: 計算機與信息工程學院 專 業: 計算機科學與技術 組 別: 第五組 起止日期: 2011年11月24日2011年12月7日指導教師: 趙國柱 計算機與信息工程學院二一一年制課程設計題目滑動窗口協議仿真組長趙育坤學號2011220135班級計專1班系別計算機與信息工程學院專業計算機科學與技術組員閆婷、張俠、余靜、于東鋒、張飛、趙育坤指導教師趙國柱課程設計目的掌握滑動窗口協議的基本原理,并能夠用所學計算機高級語言進行編程模擬課程設計所需環境開發環境: VC+ 運行環境:Windows 操作系統課程設計任務

2、要求1程序按照滑動窗口協議實現端對端的數據傳送。包括協議的各種策略,如包丟失、停等應答、超時等都應有所仿真實現2顯示數據傳送過程中的各項具體數據。雙方幀的個數變化,幀序號,發送和接受速度,暫停或重傳提示等課程設計工作進度計劃序號起止日期工 作 內 容分工情況111月24號11月27號了解工作要求,明確分工內容,網上查閱相關資料所有組員共同參與211月28號11月30號sender隊列模塊的編寫由閆婷完成312月1號12月4號sender主函數的編寫由趙育坤、張飛完成411月28號11月30號receiver隊列模塊的編寫由張俠完成512月1號12月4號receiver主函數的編寫由余靜、于東鋒

3、完成612月5號12月7號最后匯總,調試由趙育坤、于東鋒完成指導教師簽字: 年 月 日教研室審核意見:教研室主任簽字: 年 月 日課程設計任務書一. 引言二. 基本原理2.1 窗口機制2.2 1bit滑動窗口協議2.3 后退N協議2.4 選擇重傳協議2.5 流量控制三. 需求分析3.1 課程設計題目3.2 開發環境3.3 運行環境3.4 課程設計任務及要求3.5 界面要求3.6 網絡接口要求四. 詳細設計 4.1 結構體的定義4.2 發送方的主要函數4.3 接受方的主要函數五. 源代碼 5.1 發送方的主要代碼5.2 接收方的主要代碼六. 調試與操作說明 致謝參考文獻 課程設計的主要內容1.引

4、言早期的網絡通信中,通信雙方不會考慮網絡的擁擠情況直接發送數據。由于大家不知道網絡擁塞狀況,一起發送數據,導致中間結點阻塞掉包,誰也發不了數據。在數據傳輸過程中,我們總是希望數據傳輸的更快一些,但如果發送方把數據發送的過快,接收方就可能來不及接收,這就造成數據的丟失。因此就有了滑動窗口機制來解決這些問題。早期我們使用的是1bit滑動窗口協議,一次只發送一個幀,等收到ack確認才發下一個幀,這樣對信道的利用率太低了。因此提出了一種采用累積確認的連續ARQ協議,接收方不必對收到的幀逐個發送ack確認,而是收到幾個幀后,對按序到達的最后一個幀發送ack確認。同1bit滑動窗口協議相比,大大減少了ac

5、k數量,并消除了延遲ack對傳輸效率的影響。2.基本原理2.1 窗口機制滑動窗口協議的基本原理就是在任意時刻,發送方都維持了一個連續的允許發送的幀的序號,稱為發送窗口;同時,接收方也維持了一個連續的允許接收的幀的序號,稱為接收窗口。發送窗口和接收窗口的序號的上下界不一定要一樣,甚至大小也可以不同。不同的滑動窗口協議窗口大小一般不同。發送方窗口內的序號代表了那些已經被發送,但是還沒有被確認的幀,或者是那些可以被發送的幀。接受方為其窗口內的每一個序號保留了一個緩沖區。與每個緩沖區相關聯的還有一位,用來指明該緩沖區是滿的還是空的。 2.2 1bit滑動窗口協議當發送窗口和接收窗口的大小固定為1時,滑

6、動窗口協議退化為停等協議(stopandwait)。該協議規定發送方每發送一幀后就要停下來,等待接收方已正確接收的確認(acknowledgement)返回后才能繼續發送下一幀。由于接收方需要判斷接收到的幀是新發的幀還是重新發送的幀,因此發送方要為每一個幀加一個序號。由于停等協議規定只有一幀完全發送成功后才能發送新的幀,因而只用一比特來編號就夠了。其發送方和接收方運行的流程圖如圖所示。2.3 后退N協議由于停等協議要為每一個幀進行確認后才繼續發送下一幀,大大降低了信道利用率,因此又提出了后退n協議。后退n協議中,發送方在發完一個數據幀后,不停下來等待應答幀,而是連續發送若干個數據幀,即使在連續

7、發送過程中收到了接收方發來的應答幀,也可以繼續發送。且發送方在每發送完一個數據幀時都要設置超時定時器。只要在所設置的超時時間內仍收到確認幀,就要重發相應的數據幀。如:當發送方發送了N個幀后,若發現該N幀的前一個幀在計時器超時后仍未返回其確認信息,則該幀被判為出錯或丟失,此時發送方就不得不重新發送出錯幀及其后的N幀。從這里不難看出,后退n協議一方面因連續發送數據幀而提高了效率,但另一方面,在重傳時又必須把原來已正確傳送過的數據幀進行重傳(僅因這些數據幀之前有一個數據幀出了錯),這種做法又使傳送效率降低。由此可見,若傳輸信道的傳輸質量很差因而誤碼率較大時,連續測協議不一定優于停止等待協議。此協議中

8、的發送窗口的大小為k,接收窗口仍是1。2.4 選擇重傳協議在后退n協議中,接收方若發現錯誤幀就不再接收后續的幀,即使是正確到達的幀,這顯然是一種浪費。另一種效率更高的策略是當接收方發現某幀出錯后,其后繼續送來的正確的幀雖然不能立即遞交給接收方的高層,但接收方仍可收下來,存放在一個緩沖區中,同時要求發送方重新傳送出錯的那一幀。一旦收到重新傳來的幀后,就可以原已存于緩沖區中的其余幀一并按正確的順序遞交高層。這種方法稱為選擇重發(SELECTICE REPEAT),其工作過程如圖所示。顯然,選擇重發減少了浪費,但要求接收方有足夠大的緩沖區空間。2.5 流量控制TCP的特點之一是提供體積可變的滑動窗口

9、機制,支持端到端的流量控制。TCP的窗口以字節為單位進行調整,以適應接收方的處理能力。處理過程如下: (1)TCP連接階段,雙方協商窗口尺寸,同時接收方預留數據緩存區; (2)發送方根據協商的結果,發送符合窗口尺寸的數據字節流,并等待對方的確認; (3)發送方根據確認信息,改變窗口的尺寸,增加或者減少發送未得到確認的字節流中的字節數。調整過程包括:如果出現發送擁塞,發送窗口縮小為原來的一半,同時將超時重傳的時間間隔擴大一倍。(4)滑動窗口機制為端到端設備間的數據傳輸提供了可靠的流量控制機制。然而,它只能在源端設備和目的端設備起作用,當網絡中間設備(例如路由器等)發生擁塞時,滑動窗口機制將不起作

10、用。3.需求分析3.1 課程設計題目:滑動窗口協議仿真3.2 開發環境:Visual C+ 6.0 3.3 運行環境:Windows 操作系統 3.4 課程設計任務及要求: (1)程序按照滑動窗口協議實現端對端的數據傳送。包括協議的各種策略,如包丟失、停等應答、超時等都應有所仿真實現。 (2)顯示數據傳送過程中的各項具體數據。雙方幀的個數變化,幀序號,發送和接受速度,暫停或重傳提示等。3.5 界面要求:此次課程設計要求的所有功能應可視,我們組主要是用VC+編寫的,運行在DOS環境下,觀察發送方(sender)發送數據包到接收方(receive)時。3.6 網絡接口要求:兩臺機器或是一臺機器中兩

11、個獨立的線程模擬發送方與接受方,接收數據的端口初始應為監聽狀態。發送方向接受方發起連接,成功后開始發送數據。4.概要設計4.1 結構體定義如下:typedef enum data = 1,ack,nak,tout frame_kind; /幀類型typedef struct frame_head frame_kind kind; /幀類型 unsigned int seq; /序列號 unsigned int ack; /確認號 unsigned char dataMAX_LENGTH; /數據Head;typedef struct frame frame_head head; /幀頭 uns

12、igned int size; /數據的大小 Frame; typedef struct framenode /隊列節點類型 frame head_data; struct framenode *next; Framenode;typedef struct Framenode *front; /隊頭指針 Framenode *rear; /隊尾指針 LinkQueue;4.2 發送方的主要函數實現:函數名:void InitLine(LinkQueue *q);功 能:初始化隊列。函數名:void GetFrameFromHost(LinkQueue *q);功 能:從主機取數據幀,由于實驗需

13、要,假設主機有足夠多的數據幀要發送。void DeLine(LinkQueue *q);功 能:數據幀發送完畢(收到確認幀)后,刪除發送的數據幀(隊頭)。函數名:int QueueEmpty(LinkQueue *q);功 能:判斷隊列是否為空。函數名:frame QueueFront(LinkQueue *q);功 能:取隊頭,首幀是準備好待發送的幀。函數名:int QueueLen(LinkQueue *q);功 能:計算隊列長度。函數名:DWORD WINAPI ReceiveFun(LPVOID pArg);功 能:發送線程調用的函數,pArg參數存接收幀指針。函數名:void mai

14、n();功 能:發送方主函數,首先和接收方(本機"127.0.0.1")建立socket連接并初始化發送隊列。然后重復下面的步驟:(1)從主機取數據幀;(2)發送數據幀,含超時重發(接收方未收到或未收到接收方ack)和錯誤重發(收到接收方nak);(3)設置超時計時器,這里是5秒;(4)等待確認,調用CreateThread()函數創建一個線程,超時則調用TerminateThread()函數結束線程并再次發送數據幀。收到數據幀則做后續處理;(5)收到否認幀nak則再次發送數據幀,收到確認幀ack則發送下一個數據幀;(6)如果發送的測試時間達到20秒,則提示是否繼續測試,按

15、q或Q退出測試。4.3接收方的主要函數實現:函數名:void InitLine(LinkQueue *q);功 能:初始化隊列。函數名:void GetFrameFromHost(LinkQueue *q);功 能:準備好接收幀的緩沖池,首幀是待接收的幀,尾幀是已經接收的待提交主機的幀。由于實驗需要,假設數據幀送往主機是足夠快的。int DeLine(LinkQueue *q, frame *pf, unsigned int curw)功 能:將幀數據保存供提交主機,curw是打開的待接收數據的窗口。函數名:int QueueEmpty(LinkQueue *q);功 能:判斷隊列是否為空。函

16、數名:int QueueLen(LinkQueue *q);功 能:計算隊列長度。函數名:void main();功 能:接收方主函數,首先和發送方建立socket連接并初始化初始化接收窗口。然后重復下面的步驟:(1)等待,接收數據幀;(2)校驗數據幀,假定產生隨機結果,20%的概率校驗錯誤或發送方發送數據幀超時;(3)校驗錯誤時,丟棄數據幀,并發送否認幀nak;(4)如果出現接收超時(假定未收到發送方發送的數據幀),則不給發送發任何回應;(5)如果校驗正確,首先判斷是否是上一幀的重發。是上一幀的重發,則丟棄數據幀,并發送確認幀ack;是新的數據幀,則保存數據幀到當前接收窗口,并發送確認幀ac

17、k。(6)送數據幀至主機。5.源代碼5.1 發送方的主要代碼:void InitLine(LinkQueue *q) q->front = q->rear = NULL;int QueueEmpty(LinkQueue *q)return q->front = NULL && q->rear = NULL;frame QueueFront(LinkQueue *q) if (QueueEmpty(q) printf("隊列為空!n"); Sleep(SLEEPMS); exit(0); return q->front->h

18、ead_data;int QueueLen(LinkQueue *q)if (QueueEmpty(q) return 0; int num = 0;Framenode *p = q->front;while(p != NULL)num+;p = p->next;return num;void GetFrameFromHost(LinkQueue *q) if(QueueLen(q) >= MAXPOOL) printf("data %d 已準備好n", q->front->head_data.head.seq);return;Framenod

19、e *p=(Framenode *)malloc(sizeof(Framenode);memset(p->head_data.head.data, 0, MAX_LENGTH);srand(unsigned)time(NULL);p->head_data.size = rand() % MAX_LENGTH; / 幀大小隨機生成memset(p->head_data.head.data, '1', p->head_data.size);p->head_data.head.ack = -1;p->head_data.head.kind = da

20、ta;p->head_data.head.seq = 0;p->next =NULL;if(QueueEmpty(q)q->front = q->rear=p; / 首幀是待發送的幀elsep->head_data.head.seq = (q->rear->head_data.head.seq + 1)%MAXPOOL;q->rear->next =p;q->rear =p;printf("從主機得到:data %d,放入緩存n", p->head_data.head.seq);GetFrameFromHos

21、t(q); / 由于實驗需要,假設主機有足夠多的數據幀要發送void DeLine(LinkQueue *q)Framenode *p = NULL;if(QueueEmpty(q)printf("隊列為空!n");else p = q->front;q->front = p->next;if (q->rear = p) q->rear = NULL;printf("發送data %d, %d 成功!從緩存中刪除n", p->head_data.head.seq, p->head_data.size);free(

22、p);p = NULL;void main() printf("建立連接 . n");Begin:WORD wVersionRequested; WSADATA wsaData; /初始化socket庫wVersionRequested=MAKEWORD(1,1); /兩個byte型合并成一個WORD型int err=WSAStartup(wVersionRequested,&wsaData);if(err!=0) Sleep(SLEEPMS); return; if ( LOBYTE( wsaData.wVersion ) != 1 | HIBYTE( wsaDa

23、ta.wVersion ) != 1 ) WSACleanup(); /中止Windows Sockets服務 WSAStartup()成對使用Sleep(SLEEPMS); return; socketClient = socket(AF_INET,SOCK_STREAM,0);/監聽的套接字SOCKADDR_IN clientadd; clientadd.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); clientadd.sin_family = AF_INET; clientadd.sin_port = htons(700

24、1);/設置連接端的IP、端口if(SOCKET_ERROR=connect(socketClient,(SOCKADDR*)&clientadd,sizeof(SOCKADDR) ) /連接WSACleanup();Sleep(SLEEPMS);goto Begin;char getDataRECEIVE_MAX_LENGTH;memset(getData, 0, RECEIVE_MAX_LENGTH); /清零if(recv(socketClient,getData,RECEIVE_MAX_LENGTH,0) = SOCKET_ERROR) /接受 printf("接受連

25、接提示信息出錯!n"); else printf("%sn",getData); char sendDataSEND_MAX_LENGTH;memset(sendData, 0, SEND_MAX_LENGTH); strcpy(sendData, "你好接收方,我是發送方!");if( SOCKET_ERROR = send(socketClient,sendData,strlen(sendData)+1,0) ) /發送 printf("發送連接提示信息出錯!n");WSACleanup();closesocket(so

26、cketClient);Sleep(SLEEPMS); return; printf("按任意鍵繼續!n");while (!kbhit() ; /等待開始Sleep(SLEEPMS);printf("1bit滑動窗口協議:發送方,發送窗口=1n");LinkQueue QueueQ;InitLine(&QueueQ);frame packetsend; /dataframe packetreceive; / ack,nakunsigned long tick = GetTickCount(); int ret = 0;HANDLE hThrea

27、d; while(1)GetFrameFromHost(&QueueQ);/從主機取數據幀memset(&packetsend, 0, sizeof(packetsend);Sleep(SLEEPMS);printf("n");packetsend = QueueFront(&QueueQ); /取數據幀ret = send(socketClient, (char *)&packetsend, sizeof(packetsend), 0);/發送dataif(ret = SOCKET_ERROR)printf("發送數據出錯!n&q

28、uot;); continue; printf("發送數據幀:data %d, %dn", packetsend.head.seq, packetsend.size);const unsigned long timeOut = 5 * 1000; /設置超時計時器 5秒超時memset(&packetreceive, 0, sizeof(packetreceive);Sleep(SLEEPMS);printf("n");InitializeCriticalSection(&gCS); / 初始化臨界區 hThread=CreateThre

29、ad(NULL, 0, ReceiveFun, (LPVOID)&packetreceive, 0, NULL); int r = WaitForMultipleObjects(1, &hThread, TRUE, timeOut);DeleteCriticalSection(&gCS); /與InitializeCriticalSection(&gCS);成對使用if(ret = SOCKET_ERROR | ret = SOCKET_DISCONN)printf("接受出錯!Press any key to continuen"); wh

30、ile (!kbhit() ; continue; if(r = WSA_WAIT_TIMEOUT) /判斷超時TerminateThread(hThread, 0); /終止線程printf("超時重傳:data %d, %dn", packetsend.head.seq,packetsend.size); else if(packetsend.head.seq = packetreceive.head.ack)srand(unsigned)time(NULL);switch(rand() % 5) /假定產生隨機結果,20%的概率超時case 0:printf(&quo

31、t;接收方發送回復超時(ack丟失模擬):%dn", packetsend.head.seq);printf("超時重傳:data %d, %dn", packetsend.head.seq,packetsend.size);break;default:if(packetreceive.head.kind = ack) printf("接受ack幀:ack %dn", packetreceive.head.ack);DeLine(&QueueQ);else if(packetreceive.head.kind = nak)printf(

32、"接受nak幀:nak %dn", packetsend.head.seq);break;else printf("幀序號出錯: %dn", packetreceive.head.ack);if(GetTickCount() - tick > 20 * TIMEOUT) /設置時間20秒printf("持續時間20s. 按q退出,其他鍵繼續n"); int kbc = getch();if(kbc = 'q' | kbc = 'Q')break;printf("按任意鍵退出!n"

33、;); while (!kbhit() ; Sleep(SLEEPMS);printf("謝謝使用!n");WSACleanup();closesocket(socketClient);Sleep(SLEEPMS);DWORD WINAPI ReceiveFun(LPVOID pArg) EnterCriticalSection(&gCS);/進入critical sectionframe *packetreceive = (frame *)pArg;ret = recv(socketClient, (char *)packetreceive, sizeof(*pa

34、cketreceive), 0);LeaveCriticalSection(&gCS);/線程用畢,離開critical sectionreturn ret; 5.2 接收方的主要代碼:void InitLine(LinkQueue *q)q->front = q->rear = NULL;int QueueEmpty(LinkQueue *q)return q->front = NULL && q->rear = NULL;frame QueueFront(LinkQueue *q)if (QueueEmpty(q) printf("

35、隊列為空!n"); Sleep(SLEEPMS); exit(0); return q->front->head_data;int QueueLen(LinkQueue *q)if (QueueEmpty(q) return 0; int num = 0;Framenode *p = q->front;while(p != NULL)num+;p = p->next;return num;int GetFrameFromHost(LinkQueue *q)if(QueueLen(q) >= MAXPOOL)printf("準備接受:data %

36、d n", q->front->head_data.head.seq);return q->front->head_data.head.seq;Framenode *p=(Framenode *)malloc(sizeof(Framenode);memset(p->head_data.head.data, 0, MAX_LENGTH);p->head_data.head.ack = -1;p->head_data.head.kind = ack;p->head_data.head.seq = 0;p->next =NULL;if(

37、QueueEmpty(q) q->front = q->rear=p; elsep->head_data.head.seq = (q->rear->head_data.head.seq + 1)%MAXPOOL;q->rear->next =p;q->rear = p;return GetFrameFromHost(q);int DeLine(LinkQueue *q, frame *pf, unsigned int curw) /假設數據幀送往主機是足夠快的Framenode *p = NULL;if(curw = q->front-&g

38、t;head_data.head.seq) p = q->front;elsep = q->rear;if(p->head_data.head.ack != -1) /假定數據已經提交主機printf("向主機交付data %d, %d 成功!n", p->head_data.head.ack, p->head_data.size);memset(p->head_data.head.data, 0, MAX_LENGTH);memcpy(p->head_data.head.data, pf->head.data, pf->

39、;size); p->head_data.size = pf->size;p->head_data.head.ack = pf->head.seq; /保存發送幀序號return p->head_data.head.seq;frame QueueAnswer(LinkQueue *q, unsigned int curw)if(curw = q->front->head_data.head.seq) return q->front->head_data;elsereturn q->rear->head_data;void mai

40、n()Begin: WORD wVersionRequested; WSADATA wsaData; /初始化socket庫 wVersionRequested = MAKEWORD( 1, 1 ); /兩個byte型合并成一個WORD型 int err = WSAStartup(wVersionRequested, &wsaData );/使用sockets之前要調用一次if ( err != 0 ) Sleep(SLEEPMS); return; if ( LOBYTE( wsaData.wVersion ) != 1 | HIBYTE( wsaData.wVersion ) !=

41、 1 ) WSACleanup();/中止Windows Sockets服務 WSAStartup()成對使用Sleep(SLEEPMS); return; SOCKET socksrv = socket(AF_INET,SOCK_STREAM,0);/監聽的套接字 SOCKADDR_IN socketadd; socketadd.sin_addr.S_un.S_addr = htonl(INADDR_ANY); /監聽連接 socketadd.sin_family = AF_INET; socketadd.sin_port = htons(7001); /設置端口if( SOCKET_ERR

42、OR = bind(socksrv,(SOCKADDR*)&socketadd,sizeof(SOCKADDR) ) printf("綁定出錯!n");WSACleanup();Sleep(SLEEPMS); return; if( SOCKET_ERROR = listen(socksrv,5) ) printf("監聽出錯!");WSACleanup();Sleep(SLEEPMS); return; SOCKADDR_IN sockclient; int len = sizeof(SOCKADDR); SOCKET sockconn = a

43、ccept(socksrv,(SOCKADDR*)&sockclient,&len);/建立連接的套節字 if(INVALID_SOCKET = sockconn ) printf("建立連接出錯!n"); return; char sendDataSEND_MAX_LENGTH;memset(sendData, 0, SEND_MAX_LENGTH); sprintf(sendData,"%s","你好發送方,我是接受方!"); if( SOCKET_ERROR = send(sockconn,sendData,st

44、rlen(sendData)+1,0) ) printf("發送連接提示信息出錯!n");WSACleanup( );closesocket(sockconn);Sleep(SLEEPMS); return; char getDataRECEIVE_MAX_LENGTH;memset(getData, 0, RECEIVE_MAX_LENGTH); recv(sockconn,getData,RECEIVE_MAX_LENGTH,0); printf("%sn",getData);printf("1bit滑動窗口協議:接收方,接收窗口=1n&q

45、uot;);LinkQueue QueueQ;InitLine(&QueueQ);frame packetreceive; /dataframe packetsend; / ack,nakint curw = GetFrameFromHost(&QueueQ);/初始化接收窗口int ret = 0;while(1)memset(&packetreceive, 0, sizeof(packetreceive);Sleep(SLEEPMS);printf("n");ret = recv(sockconn,(char *)&packetrecei

46、ve, sizeof(packetreceive), 0);if(ret = SOCKET_ERROR | ret = SOCKET_DISCONN)if(ret = SOCKET_ERROR)printf("連接出錯!自動連接!n"); continue;elseprintf("連接已斷開,按q退出,其他鍵等待新的連接n"); int kbc = getch();if(kbc = 'q' | kbc = 'Q')break;else WSACleanup();closesocket(sockconn);Sleep(SLE

47、EPMS);goto Begin;srand(unsigned)time(NULL);switch(rand() % 5) /假定產生隨機結果,20%的概率校驗錯誤或接收發送方超時case 0:printf("接受數據幀:data %d, %d,校驗錯誤,丟棄(數據幀出錯模擬)n", packetreceive.head.seq, packetreceive.size);memset(&packetsend, 0, sizeof(packetsend);memcpy(&packetsend, &packetreceive, sizeof(packetreceive);packetsend.head.ack = packetreceive.head.seq;packetsend.head.seq = curw;packetsend.head.kind = nak;printf("發送否認幀:nak %dn", packetreceive.head.seq);break;case 1:packetsend.head.kind = tout; printf("發送方發送數據超時(數據幀丟失模擬)

溫馨提示

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

評論

0/150

提交評論