版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年環(huán)保能源股份收購協(xié)議范本3篇
- 基于云計算的二零二五年度企業(yè)安全防護合同2篇
- 二零二五年度高端建筑用板材夾板購銷合同3篇
- 二零二五版別墅買賣協(xié)議書模板(含合同履行期限)4篇
- 二零二五年度二手房買賣居間服務(wù)與租賃管理合作協(xié)議正本4篇
- 2025年度高端酒店芒果供應(yīng)與銷售合作協(xié)議4篇
- 二零二五版出租車行業(yè)車輛維修配件供應(yīng)協(xié)議3篇
- 二零二五年集裝箱貨物運輸保險合同2篇
- 2025年洗車場租賃與員工服務(wù)協(xié)議3篇
- 2025年度鋁合金門窗產(chǎn)品檢測與認證服務(wù)合同4篇
- 2023年消防接警員崗位理論知識考試參考題庫(濃縮500題)
- GB/T 30285-2013信息安全技術(shù)災(zāi)難恢復(fù)中心建設(shè)與運維管理規(guī)范
- 魯濱遜漂流記閱讀任務(wù)單
- 第一章 運營管理概論1
- 《創(chuàng)意繪畫在小學(xué)美術(shù)教育中的應(yīng)用(論文)6000字》
- 主體結(jié)構(gòu)驗收匯報材料T圖文并茂
- 管理學(xué)原理(南大馬工程)
- 過一個有意義的寒假課件
- 施工現(xiàn)場裝配式集裝箱活動板房驗收表
- 電力業(yè)擴工程竣工驗收單
- 三年級上冊口算題(1000道打印版)
評論
0/150
提交評論