計算機網(wǎng)絡(luò)實驗報告_第1頁
計算機網(wǎng)絡(luò)實驗報告_第2頁
計算機網(wǎng)絡(luò)實驗報告_第3頁
計算機網(wǎng)絡(luò)實驗報告_第4頁
計算機網(wǎng)絡(luò)實驗報告_第5頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、計算機網(wǎng)絡(luò)實驗報告姓名:班級: 學(xué)號:實驗日期:2011年12月1、題目:ARQ協(xié)議的模擬實現(xiàn)2、環(huán)境:在visual studio 環(huán)境下,采用c+程序設(shè)計語言,模擬實現(xiàn)ARQ協(xié)議。3、實驗內(nèi)容: p1模擬發(fā)送方:首先從界面讀取待發(fā)送字符(每接受一個字符的輸入),保存到文件file1.txt中,并啟動計時器;p2模擬接收方,它從file1.txt中查找是否有新字符到來,并提供模擬界面給用戶選擇: 1. Ack-接收該字符 2. NAK-丟棄 3. 無反應(yīng)-導(dǎo)致超時 將用戶選擇的結(jié)果記錄到file2.txt中; 接收的字符保存到file3.txt 中;n p1等待接收方應(yīng)答:讀取file2.t

2、xt 決定下面的操作:n 如果是ACK,則繼續(xù)接收用戶輸入;n 如果是NAK,則重傳該字符;n 如果超時仍沒有新的ACK或NAK,則重傳該字符。n 注:file1.txt要發(fā)送的串, file2.txt保存中間結(jié)果, file3.txt接受的串,由實驗者自己生成。4、實驗步驟:(1)編寫receiver()函數(shù)模擬接收端的相應(yīng)處理過程;(2)編寫sender()函數(shù)模擬發(fā)送端相應(yīng)處理過程,其中sender函數(shù)調(diào)用了receiver()函數(shù);(3)編寫主函數(shù)main()函數(shù),調(diào)用sender()和receiver()函數(shù)來實現(xiàn)整個發(fā)送接收過程,進而模擬了ARQ協(xié)議的實現(xiàn)。5、 實驗中的問題及心得

3、:ARQ協(xié)議中,發(fā)送方每發(fā)送一個字符便要啟動計時器,在規(guī)定時間內(nèi),若發(fā)送方未收到接收方返回的確認信息,則認為超時,需重發(fā)原字符。經(jīng)過思考,我通過for循環(huán)反復(fù)讀取file2文件實現(xiàn)了這一定時功能,而循環(huán)的次數(shù)則決定定時器的時間。此外還可利用c+語言自帶的time()函數(shù)來實現(xiàn)計時功能。此外,為方便讀取中間結(jié)果,file2文件的內(nèi)容每次都會更新,并且采用簡單的字符代表復(fù)雜的字符串,這些簡化都使程序更加簡潔,但并未影響整個模擬功能的實現(xiàn)。為了更加流暢地更新、利用文件中的數(shù)據(jù),sender()函數(shù)調(diào)用了receiver()函數(shù),以及時對文件數(shù)據(jù)進行接收端的相應(yīng)處理,以供發(fā)送端使用。從而模擬實現(xiàn)整個發(fā)

4、送接收過程。6、 通過實驗所掌握的內(nèi)容通過此次試驗,我對ARQ協(xié)議的原理以及基本工作過程有了更深入的理解、掌握。同時在一定程度上增強了我的獨立編程能力和獨立思考能力。越來越發(fā)現(xiàn),編程其實沒那么難,但想成為高手也很不容易。ARQ協(xié)議的模擬實現(xiàn)代碼如下:#include #include #include /下面是兩個函數(shù)原型void receiver(int ,fstream &,fstream &,ofstream &);/接收方void sender(fstream &datafile1,fstream &datafile2,ofstream &datafile3);/發(fā)送方void mai

5、n()fstream datafile1,datafile2;ofstream datafile3;cout下面開始數(shù)據(jù)的傳輸,注意:傳輸數(shù)據(jù)以“!”結(jié)束endl; sender(datafile1,datafile2,datafile3);cout數(shù)據(jù)傳輸結(jié)束endl;/接收端void receiver(int i,fstream &datafile1,fstream &datafile2,ofstream &datafile3)char r,re;datafile1.open(file1,ios:out|ios:in);if(!datafile1) cout文件打開失敗!=A&r=Z)/若

6、讀取的字符有效,即正確接受字符 datafile3.open(file3,ios:app); if(!datafile3) cout文件打開失敗!endl; exit(0); datafile3r;/將收到的字符寫入文件file3 cout字符已正確接收endl; cout準(zhǔn)備發(fā)送確認信息ACKendl; cout請輸入A,并以回車結(jié)束re; datafile2.open(file2,ios:out); if(!datafile2) cout文件打開失??!endl; exit(0); datafile2re;/將確認信息寫入file2 if(rZ)/讀取的字符無效,即接受字符出錯 cout接收

7、字符錯誤endl; cout準(zhǔn)備發(fā)送信息NAKendl; coutre; datafile3.open(file3); if(!datafile3) cout文件打開失??!endl; exit(0); datafile3re;/返回出錯信息,將N寫入file3 datafile1.close(); datafile2.close(); datafile3.close();/發(fā)送端void sender(fstream &datafile1,fstream &datafile2,ofstream &datafile3)char s,st;long i=0; cout整個信息輸入以“!”結(jié)束;co

8、uts;datafile1.open(file1,ios:out|ios:in);if(!datafile1)cout文件打開失?。ndl;exit(0);datafile1s;/發(fā)送信息,即將待發(fā)送的字符寫入文件file1 i+;cout字符已被發(fā)送endl;datafile1.close();receiver(i,datafile1,datafile2,datafile3);/調(diào)用接收端進行相應(yīng)操作while(1)if(s=!)break;for(int t=1;t=4;t+)/起定時器的作用datafile2.open(file2,ios:in);if(!datafile2) cout

9、文件打開失敗!endl; exit(0);datafile2.get(st);datafile2.close(); if(st=A)/發(fā)送方收到接收方的確認信息ACK cout上一個字符已被接收!endl; couts; datafile1.open(file1,ios:out|ios:in); if(!datafile1) cout文件打開失敗!endl; exit(0); datafile1s;/將新的待發(fā)送字符寫入file1 i+; cout字符已被發(fā)送endl; datafile1.close();receiver(i,datafile1,datafile2,datafile3);/調(diào)

10、用接收端進行相應(yīng)操作 break; if(st=N)/發(fā)送方收到接收方的出錯信息NAK cout上一個字符出錯!endl; cout現(xiàn)在需重新發(fā)送原字符endl; datafile1.open(file1,ios:out|ios:in); if(!datafile1) cout文件打開失??!endl; exit(0);datafile1s; i+; cout字符已被發(fā)送endl; datafile1.close(); receiver(i,datafile1,datafile2,datafile3);/調(diào)用接收端進行相應(yīng)操作 break; cout定時器超時,現(xiàn)重新發(fā)送原字符。endl; da

11、tafile1.open(file1,ios:out|ios:in); if(!datafile1) cout文件打開失敗!endl; exit(0);datafile1s; i+; cout字符已被發(fā)送endl; datafile1.close(); receiver(i,datafile1,datafile2,datafile3);/調(diào)用接收端進行相應(yīng)操作RIP協(xié)議實驗一:實驗?zāi)康耐ㄟ^交互實驗和編程實驗,深入理解RIP協(xié)議的工作原理,了解RIP協(xié)議分組接收和發(fā)送流程以及路由表的維護,進一步掌握計算機網(wǎng)絡(luò)的核心技術(shù)路由技術(shù),培養(yǎng)路由協(xié)議編程開發(fā)能力。二:實驗原理三:實驗過程以及代碼解釋實驗代

12、碼:#include sysinclude.h#include extern void rip_sendIpPkt(unsigned char* pData, UINT16 len, unsigned short dstPort, UINT8 iNo);/*RIP包的發(fā)送函數(shù)*/extern struct stud_rip_route_node *g_rip_route_table;/*路由表*/typedef struct _packet_header /*RIP數(shù)據(jù)包的頭部*/unsigned char command;/*命令只能是REQUEST或者RESONSE*/unsigned c

13、har version;/*版本號,1或者2*/unsigned short pad0;/*置零*/ packet_header;typedef struct _packet_data/*RIP數(shù)據(jù)包*/unsigned short addrfamily;/*地址族,必須為2*/unsigned short routetag;/*路由標(biāo)記*/unsigned int ipaddr;/*IP地址*/unsigned int netmask;/*掩碼*/unsigned int nexthop;/*下一跳*/unsigned int metric;/*跳數(shù)*/ packet_data;#defin

14、e DECLAREERROR(pkt,type) printf(Discard because %dn,type);ip_DiscardPkt(pkt,type);return 0;/*定義RIP包出錯時的返回類型*/unsigned char buffer256;/*緩沖區(qū)*/void dumpPkt(unsigned char*buf,int len)/*實現(xiàn)數(shù)據(jù)提取功能*/printf(Dump sending packet:n);int l=0;for (int i=0;iif_no=iNo|pnow-metric=16)pnow=pnow-next;/*遍歷并復(fù)制路由鏈表*/do/*

15、組裝RIP數(shù)據(jù)包的頭部*/packet_header*ph=(packet_header*)buffer;ph-command=2; /*響應(yīng)(RESPONSE)分組*/ph-version=version; /*版本號*/ph-pad0=0; /*必須為0*/*組裝數(shù)據(jù)包*/int pCount=0;while (pCountaddrfamily=htons(2); pd-routetag=0; pd-ipaddr=htonl(pnow-dest);if (version=2)pd-netmask=htonl(pnow-mask);elsepd-netmask=0;if (version=2

16、)pd-nexthop=htonl(pnow-nexthop);elsepd-nexthop=0;pd-metric=htonl(pnow-metric);pCount+;do pnow=pnow-next; while (pnow&(pnow-if_no=iNo|pnow-metric=16);/*發(fā)送數(shù)據(jù)包*/dumpPkt(buffer,sizeof(packet_header)+sizeof(packet_data)*pCount);rip_sendIpPkt(buffer,sizeof(packet_header)+sizeof(packet_data)*pCount,520,iNo

17、); while (pnow);#include char*clone(char*org,int len)/*取出數(shù)據(jù)并刪除緩沖區(qū)的原始數(shù)據(jù)*/char*t=(char*)malloc(len);memmove(t,org,len);return t;int stud_rip_packet_recv(char*pBuffer, int bufferSize, UINT8 iNo, UINT32 srcAdd)pBuffer=clone(pBuffer,bufferSize);/*檢查數(shù)據(jù)包頭部是否合法,否則調(diào)用出錯函數(shù)返回出錯類型*/packet_header*ph=(packet_heade

18、r*)pBuffer;if (ph-command!=1&ph-command!=2) DECLAREERROR(pBuffer,STUD_RIP_TEST_COMMAND_ERROR);if (ph-version!=1&ph-version!=2) DECLAREERROR(pBuffer,STUD_RIP_TEST_VERSION_ERROR);if (ph-pad0!=0) DECLAREERROR(pBuffer,STUD_RIP_TEST_COMMAND_ERROR);if (ph-command=1)/*為REQUEST包*/printf(Get valid requestn);

19、MakePacket(ph-version,iNo);else/*為RESPONSE包*/dumpPkt(unsigned char*)pBuffer,bufferSize);/*從緩沖區(qū)取出數(shù)據(jù)組包*/int snums=(bufferSize-sizeof(packet_header)/sizeof(packet_data);/*計算緩沖區(qū)RIP包的總數(shù)*/for (int i=0;iipaddr=ntohl(pd-ipaddr);pd-netmask=ntohl(pd-netmask);pd-nexthop=ntohl(pd-nexthop);pd-metric=ntohl(pd-met

20、ric);/*給RIP鏈表里的每一項賦值*/stud_rip_route_node*hd=g_rip_route_table;printf(offset: %d, ip: %08x, mask: %08x, nh: %08x, metric: %08x, if: %xn,(int)pd)-(int)buffer,pd-ipaddr,pd-netmask,pd-nexthop,pd-metric,iNo);dumpPkt(unsigned char*)pd,sizeof(packet_data);int hdcount=0;while (hd) if (hd-dest=pd-ipaddr&hd-

21、mask=pd-netmask) break;/*實現(xiàn)水平分割*/hd=hd-next;hdcount+;do/*對傳來的RIP數(shù)據(jù)進行分析,更新本地路由表*/if (hd) /*如果下一跳不是原來表中的下一跳,只有當(dāng)跳數(shù)更低時,更新表項*/printf(Match at %d and nexthop %xn,hdcount,hd-nexthop);if (hd-nexthop!=pd-nexthop)if (hd-metricpd-metric)hd-metric=pd-metric+1;/*跳數(shù)加一*/hd-nexthop=pd-nexthop;/*目的地更新*/hd-if_no=iNo;

22、break;/*如果下一跳滿足,直接更新RIP鏈表*/hd-metric=pd-metric+1;hd-nexthop=pd-nexthop;hd-if_no=iNo;/*如果跳數(shù)為16顯然不合法,大于16的置為16*/if (hd-metric16)hd-metric=16;else /*如果不存在則創(chuàng)建新節(jié)點(鏈表)*/printf(Unmatch.n);if (pd-metric=16) break;/*跳過跳數(shù)為16的項目*/stud_rip_route_node* nhd=(stud_rip_route_node*)malloc(sizeof(stud_rip_route_node)

23、;/*創(chuàng)建新節(jié)點*/nhd-dest=pd-ipaddr;nhd-mask=pd-netmask;nhd-nexthop=pd-nexthop;nhd-metric=pd-metric+1;/*初始值為1*/nhd-if_no=iNo;nhd-next=g_rip_route_table;/*插入路由鏈表的頭部*/g_rip_route_table=nhd; while (false);/*超時處理函數(shù)*/void stud_rip_route_timeout(UINT32 destAdd, UINT32 mask, unsigned char msgType)if (msgType=RIP_

24、MSG_SEND_ROUTE)/*向兩個端口都廣播自己的路由表*/MakePacket(2,1);MakePacket(2,2);else if (msgType=RIP_MSG_DELE_ROUTE)stud_rip_route_node*hd=g_rip_route_table;while (hd) if (hd-dest=destAdd&hd-mask=mask)break;hd=hd-next;/*傳入超時的路由表項,將跳數(shù)置為16,此時該表項會被自動刪除*/hd-metric=16;FTP協(xié)議實驗報告l 實驗?zāi)康?、在Linux系統(tǒng)上完成一個文件傳輸協(xié)議(FTP)的簡單實現(xiàn)。2、深入

25、理解FTP協(xié)議的原理和協(xié)議細節(jié)。3、學(xué)會利用Socket接口設(shè)計實現(xiàn)簡單應(yīng)用層協(xié)議。4、掌握TCP/IP網(wǎng)絡(luò)應(yīng)用程序的基本設(shè)計方法和實現(xiàn)技巧。l 實驗原理1、FTP協(xié)議2、socket編程(1)什么是Socket(2)Socket的建立(3)Socket配置 (4)連接建立(5)結(jié)束傳輸l 實驗內(nèi)容在Linux系統(tǒng)上使用Socket接口實現(xiàn)FTP客戶端 和服務(wù)器的程序,使客戶端可以連接至服務(wù)器,并且可以進行一些FTP的基本操作,如列出目錄、下載文件等。從FTP協(xié)議的實現(xiàn)角度來看,客戶端 與服務(wù)器的命令通道和數(shù)據(jù)通道需要分享,同時應(yīng)該支持以下一些FTP命令:get:取遠方的一個文件。put:傳給

26、遠方一個文件。pwd:顯示遠方當(dāng)前目錄。dir:列出遠方當(dāng)前目錄。cd:改變遠方當(dāng)前目錄。?:顯示你提供的命令quit:退出返回l 實驗過程1、實現(xiàn)服務(wù)器端(1)全局變量為了記錄緩沖區(qū)大小、當(dāng)前目錄、當(dāng)前工作路徑、幫助信息而定義了以下幾個全局變量: #define dataLen 1024 /緩沖區(qū)大小char currentDirPath200; /當(dāng)前工作目錄的絕對路徑char currentDirName30; /當(dāng)前目錄的名稱char help=getget a file from servernputupload a file to servernpwddisplay the cur

27、rent directory of serverndirdisplay the files in the current directory of serverncdchange the directory of servern?display the whole command which equals helpnquit returnn; /幫助信息(2)函數(shù)在服務(wù)器端實現(xiàn)了以下幾個函數(shù):char *getDirName(char *dirPathName); /根據(jù)當(dāng)前工作目錄的絕對路徑得到當(dāng)前目錄名稱void cmd_pwd(int sock); /處理pwd命令void cmd_di

28、r(int sock); /處理dir命令void cmd_cd(int sock,char *dirName); /處理cd命令void cmd_help(int sock); /處理?命令void cmd_get(int sock,char*fileName); /處理get命令void cmd_put(int sock,char *fileName); /處理put命令(3)主函數(shù)的實現(xiàn):先建立數(shù)據(jù)通道和命令通道,然后監(jiān)聽,若有客戶端連上,則建立一個子進程,先向客戶端發(fā)送幫助信息,然后根據(jù)客戶端的命令來調(diào)用上述各函數(shù)來處理。int main(int argc,char *argv)int

29、 sock; /服務(wù)器用于監(jiān)聽的數(shù)據(jù)通道int sockmsg; /服務(wù)器用于監(jiān)聽的命令通道 char client_cmd10; /客戶端出發(fā)的命令char cmd_arg20; /客戶端輸入的文件或目錄名,用在cd,put,get命令中struct sockaddr_in server; /服務(wù)器數(shù)據(jù)通道的信息struct sockaddr_in servermsg; /服務(wù)器命令通道的信息int datasock; /用于通信的數(shù)據(jù)通道int msgsock; /用于通信的命令通道pid_t child; /client子進程sock=socket(AF_INET,SOCK_STREAM

30、,0); /創(chuàng)建用于傳數(shù)據(jù)的套接字 sockmsg=socket(AF_INET,SOCK_STREAM,0); /創(chuàng)建用于傳消息的套接字 int opt = 1,opt2 = 1; setsockopt(sock , SOL_SOCKET , SO_REUSEADDR , &opt , sizeof(opt); /實現(xiàn)sock的重用 setsockopt(sockmsg , SOL_SOCKET , SO_REUSEADDR , &opt2 , sizeof(opt2);/實現(xiàn)sockmsg的重用 if (sock 0 | sockmsg 0) /socket創(chuàng)建失敗 perror(open

31、ing stream socket); exit(1); memset(&server,0,sizeof(server);server.sin_family=AF_INET; /設(shè)置協(xié)議族server.sin_addr.s_addr=htonl(INADDR_ANY); /監(jiān)聽所有地址server.sin_port=htons(45000); /端口設(shè)為45000memset(&servermsg,0,sizeof(servermsg);servermsg.sin_family=AF_INET; /設(shè)置協(xié)議族servermsg.sin_addr.s_addr=htonl(INADDR_ANY)

32、; /監(jiān)聽所有地址servermsg.sin_port=htons(45001); /端口設(shè)為45001 if (bind(sock,(struct sockaddr *) &server,sizeof(server) 0 | bind(sockmsg,(struct sockaddr *) &servermsg,sizeof(servermsg) 0)/連接不成功perror(binding stream socket);exit(1); int length = sizeof(server);int lengthmsg = sizeof(servermsg);if (getsockname

33、(sock,(struct sockaddr *) &server,&length) 0 | getsockname(sockmsg,(struct sockaddr *) &servermsg,&lengthmsg) 0)/得到套接字的本地名字perror(getting socket name);exit(1);printf(Socket port # %d %dn,ntohs(server.sin_port),ntohs(servermsg.sin_port);memset(currentDirPath,0,sizeof(currentDirPath);getcwd(currentDir

34、Path,sizeof(currentDirPath);/將當(dāng)前工作目錄的絕對路徑復(fù)制到/currentDirPath中l(wèi)isten(sock,2); /監(jiān)聽數(shù)據(jù)通道listen(sockmsg,2); /監(jiān)聽命令通道while(1)datasock = accept(sock,(struct sockaddr*)0,(int*)0); /與客戶端的數(shù)據(jù)通道連接msgsock = accept(sockmsg,(struct sockaddr*)0,(int*)0); /與客戶端的命令通道連接if (datasock = -1 | msgsock=-1)perror(accept);elsei

35、f(child = fork() = -1) /出錯printf(Fork Error!n);if(child = 0) /子進程printf(connection accepted! new client comingn);write(datasock,help,strlen(help) + 1);loop:memset(client_cmd,0,sizeof(client_cmd);int rval = 0;rval = read(msgsock,client_cmd,sizeof(client_cmd);/讀命令printf(%dn,rval);if(rval = 0;i -) /找到最

36、后一個/號,之后的字符串即為當(dāng)前工作目錄名稱if(dirPathNamei = /) pos=i;break;dirName = (char *)malloc(len - pos + 1);for(i = pos + 1;i = len;i +)dirNamei - pos - 1 = dirPathNamei;return dirName;(5)void cmd_pwd(int sock)的實現(xiàn):調(diào)用getDirName函數(shù)來得到當(dāng)前工作目錄名稱,然后發(fā)到客戶端void cmd_pwd(int sock)int len; char *savePointer = getDirName(currentDirPath); /得到當(dāng)前工作目錄名稱strcpy(currentDirName,savePointer);len = strlen(currentDirName) + 1;wri

溫馨提示

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

評論

0/150

提交評論