TCP協(xié)議實驗可編輯范本_第1頁
TCP協(xié)議實驗可編輯范本_第2頁
TCP協(xié)議實驗可編輯范本_第3頁
TCP協(xié)議實驗可編輯范本_第4頁
TCP協(xié)議實驗可編輯范本_第5頁
已閱讀5頁,還剩6頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

網絡課第四次上機實驗報告————-—TCP協(xié)議實驗實驗內容實驗內容主要包括:設計保存TCP連接相關信息的數據結構(TCB);TCP協(xié)議的接收處理和封裝發(fā)送;TCP協(xié)議提供的Socket函數接口。實驗過程設計保存TCP連接相關信息的數據結構(TCB)用數據結構TCB為每一個TCP連接維護socketfd,srcAddr,dstAddr,srcPort,dstPort,seq,ack,windowSize,state這些狀態(tài)信息.以鏈表形式組織多個連接,nextTcb指向下一個連接的數據結構。TCP分組接收函數stud_tcp_input()首先,檢查校驗和;然后通過字節(jié)序轉換獲取相應的信息,檢查序列號。如果序列號不正確,則調用tcp_DiscardPkt;最后將報文交由輸入有限狀態(tài)機處理,有限狀態(tài)機對報文進行處理,轉換狀態(tài)。根據當前的狀態(tài)并調用stud_tcp_output函數完成tcp建連、數據傳遞時返回ACK、tcp斷連等工作TCP分組發(fā)送函數stud_tcp_output()判斷需要發(fā)送的報文類型,根據報的類型對包中的相應字段進行設置,判斷是否可以發(fā)送(發(fā)送窗口不為0)。構造TCP數據報文并發(fā)送。填寫TCP報文各字段的內容和數據,轉換字節(jié)序,計算校驗和,然后調用發(fā)送流程的下層接口函數sendIpPkt()發(fā)送.stud_tcp_socket()函數分配相應的socketfd并且新建TCB表項,并對成員變量進行初始化stud_tcp_connect()函數設定目的IPv4地址和端口,源IPv4地址和端口;初始化TCB結構中的相關變量;設定TCB中的輸入狀態(tài)為SYN-SENT,及其它相關變量,準備發(fā)送SYN報文;調用發(fā)送流程的下層接口函數stud_tcp_output()發(fā)送SYN報文(發(fā)送類型為PACKET_TYPE_SYN);等待“三次握手"完成后返回,建立連接成功;或者出錯返回。stud_tcp_send()函數判斷是否處于ESTABLISHED狀態(tài);將應用層協(xié)議的數據拷貝到TCB的輸入緩沖區(qū);調用stud_tcp_output()發(fā)送TCP的數據報文(發(fā)送類型為PACKET_TYPE_DATA);同時等待ACK以實現(xiàn)停等式協(xié)議stud_tcp_recv()函數判斷是否處于ESTABLISHED狀態(tài);從TCB的輸入緩沖區(qū)讀出數據;將數據交給應用層協(xié)議。stud_tcp_close()函數在正常情況下(ESTABLISHED狀態(tài)),進行相應狀態(tài)轉換,非正常情況下(SYN-SENT狀態(tài)),直接刪除TCB結構后退出;調用發(fā)送流程下層接口函數stud_tcp_output()發(fā)送FIN報文(發(fā)送類型為PACKET_TYPE_FIN);等待回應的ACK報文,收到后成功返回,或者出錯返回;刪除相應的TCB表項.實驗總結通過本次實驗,加深了對TCP協(xié)議的原理和設計實現(xiàn)的機制的了解,對TCP協(xié)議有了更具體的認識,對概論課的學習有很大的幫助!附:上機代碼(注釋)#include”sysInclude.h"externvoidtcp_DiscardPkt(char*pBuffer,inttype);externvoidtcp_sendReport(inttype);externvoidtcp_sendIpPkt(unsignedchar*pData,UINT16len,unsignedintsrcAddr,unsignedintdstAddr,UINT8 ttl);externintwaitIpPacket(char*pBuffer,inttimeout);externunsignedintgetIpv4Address();externunsignedintgetServerIpv4Address();#defineBUFFER_SIZE1024#defineTIMEOUT5enumstatus{CLOSED,SYN_SENT,ESTABLISHED,FIN_WAIT_1,FIN_WAIT_2,TIME_WAIT};//狀態(tài)intgSrcPort=2007;intgDstPort=2006;intgSeqNum=1;intgAckNum=0;structTCB{ intsocketfd; UINT32srcAddr;?UINT32dstAddr; UINT16srcPort;?UINT16dstPort; UINT32seq; UINT32ack;?UINT16windowSize; UINT8state;?TCB*nextTcb;?TCB(){//用于TCP報文接收發(fā)送流程?socketfd=0; srcAddr=getIpv4Address();?dstAddr=getServerIpv4Address(); srcPort=gSrcPort;?dstPort=gDstPort; seq=gSeqNum;?ack=gAckNum;?windowSize=1; state=CLOSED; nextTcb=NULL;?}?TCB(intfd){//用于客戶端socket函數的構建函數 socketfd=fd;?seq=gSeqNum; ack=gAckNum;?windowSize=1;?state=CLOSED;?nextTcb=NULL; }};UINT16CalcChecksum(char*pBuffer,intlen,UINT32srcAddr,UINT32dstAddr){ inttcp_len=len+12;?UINT32checkSum=0;?if(tcp_len&0x1==1)tcp_len+=1;?char*buffer=newchar[tcp_len]; memset(buffer,0,tcp_len); memcpy(buffer+12,pBuffer,len);?*((UINT32*)buffer)=htonl(srcAddr);?*((UINT32*)(buffer+4))=htonl(dstAddr);?buffer[9]=6; //傳輸層協(xié)議號?*((UINT16*)(buffer+10))=htons(len); for(inti=0;i〈tcp_len;i+=2){?checkSum+=*((UINT16*)(buffer+i)); }?checkSum=(checkSum&0xFFFF)+(checkSum〉>16); checkSum=~checkSum; returncheckSum;}TCB*tcbLinkTable=NULL;//TCB鏈表/*通過兩端的IP地址和端口號尋找TCB表項*/TCB*findTCB(UINT32srcAddr,UINT16srcPort,UINT32dstAddr,UINT16dstPort){ TCB*tcb=tcbLinkTable; while(tcb!=NULL){ if((tcb—>srcAddr==srcAddr)&&(tcb—〉srcPort==srcPort)&&(tcb—>dstAddr==dstAddr)&&(tcb—>dstPort==dstPort)) returntcb; tcb=tcb-〉nextTcb;?} returnNULL;}intstud_tcp_input(char*pB(yǎng)uffer,unsignedshortlen,unsignedintsrcAddr,unsignedintdstAddr){ /*檢查校驗和*/?if(CalcChecksum(pBuffer,len,ntohl(srcAddr),ntohl(dstAddr))?。?) return—1;?UINT16srcPort=ntohs(*(UINT16*)pB(yǎng)uffer);?UINT16dstPort=ntohs(*(UINT16*)(pB(yǎng)uffer+2));?UINT32seq=ntohl(*((UINT32*)(pBuffer+4))); UINT32ack=ntohl(*((UINT32*)(pB(yǎng)uffer+8)));?UINT8flags=(pBuffer[13]&0x13);?TCB*tcb=findTCB(ntohl(dstAddr),dstPort,ntohl(srcAddr),srcPort);?if(tcb==NULL){?return-1;?}?if(ack!=tcb—〉seq+1){ tcp_DiscardPkt(pB(yǎng)uffer,STUD_TCP_TEST_SEQNO_ERROR); return—1;?}?/*有限狀態(tài)機轉換*/?if((tcb—>stat(yī)e==SYN_SENT)&&(flags==0x12)){ tcb—>seq=ack;?tcb->ack=seq+1;?stud_tcp_output(NULL,0,PACKET_TYPE_ACK,tcb—>srcPort,tcb—>dstPort,tcb—〉srcAddr,tcb—〉dstAddr);?tcb—〉state=ESTABLISHED;?}elseif((tcb->state==FIN_WAIT_1)&&(flags==0x10)){?tcb—>state=FIN_WAIT_2; }elseif((tcb->state==FIN_WAIT_2)&&(flags==0x11)){?tcb—〉ack=seq+1; tcb-〉seq=ack;?tcb->state=TIME_WAIT;?stud_tcp_output(NULL,0,PACKET_TYPE_ACK,tcb—〉srcPort,tcb—>dstPort,tcb—>srcAddr,tcb-〉dstAddr);?tcb-〉state=CLOSED;?}?return0;}voidstud_tcp_output(char*pDat(yī)a,unsignedshortlen,unsignedcharflag,unsignedshortsrcPort,unsignedshortdstPort,unsignedintsrcAddr,unsignedintdstAddr){ TCB*tcb=findTCB(srcAddr,srcPort,dstAddr,dstPort);//尋找TCB項?if(tcbLinkTable==NULL)//用于TCP報文接收發(fā)送流程{?tcb=newTCB(); tcbLinkTable=tcb; } if(tcb==NULL||tcb->windowSize==0)return; /*構造新的發(fā)送報文*/?unsignedchar*packet=newunsignedchar[len+20]; memset(packet,0,len+20);?memcpy(packet+20,pData,len);?*(UINT16*)(packet)=htons(tcb->srcPort);?*(UINT16*)(packet+2)=htons(tcb-〉dstPort);?*(UINT32*)(packet+4)=htonl(tcb-〉seq);?*((UINT32*)(packet+8))=htonl(tcb-〉ack);?packet[12]=20〈<2; switch(flag)?{ casePACKET_TYPE_SYN:?packet[13]=0x02; tcb-〉state=SYN_SENT;?//發(fā)送SYN報文,狀態(tài)轉移為SYN_SENT break;?casePACKET_TYPE_ACK:?packet[13]=0x10;?break;?casePACKET_TYPE_SYN_ACK:?packet[13]=0x12;?break; casePACKET_TYPE_FIN: packet[13]=0x01; break; casePACKET_TYPE_FIN_ACK:?packet[13]=0x11;?tcb->state=FIN_WAIT_1;?break; casePACKET_TYPE_DATA: break; }?*((UINT16*)(packet+14))=htons(tcb->windowSize);?*((UINT16*)(packet+16))=CalcChecksum((char*)packet,len+20,srcAddr,dstAddr); tcp_sendIpPkt(packet,len+20,tcb—〉srcAddr,tcb—>dstAddr,255); return;}intstud_tcp_socket(intdomain,inttype,intprotocol){ staticint?socketfd=1;?TCB*tcb=newTCB(socketfd++);?tcb—〉nextTcb=tcbLinkTable;?tcbLinkTable=tcb;?returntcb->socketfd;}intstud_tcp_connect(intsockfd,structsockaddr_in*addr,intaddrlen){?charbuffer[BUFFER_SIZE];?TCB*tcbPointer=tcbLinkTable;?while((tcbPointer!=NULL)&&(tcbPointer—>socketfd!=sockfd))tcbPointer=tcbPointer—>nextTcb; TCB*tcb=tcbPointer;//找到TCB相應表項?if(tcb==NULL)return-1; /*初始化源和目的的地址及端口號*/?tcb—〉srcAddr=getIpv4Address(); tcb—>srcPort=gSrcPort; tcb->dstAddr=ntohl(addr—>sin_addr。s_addr);?tcb—>dstPort=ntohs(addr-〉sin_port); /*建立連接:發(fā)送SYN報文*/ stud_tcp_output(NULL,0,PACKET_TYPE_SYN,tcb->srcPort,tcb->dstPort,tcb->srcAddr,tcb->dstAddr);?/*接收SYN_ACK報文*/ if(waitIpPacket(buffer,TIMEOUT)==—1||(buffer[13]&0x13)?。?x12)return—1;?tcb—>seq=ntohl(*((UINT32*)(buffer+8)));?tcb->ack=ntohl(*((UINT32*)(buffer+4)))+1; /*發(fā)送ACK報文,建立連接完成*/ stud_tcp_output(NULL,0,PACKET_TYPE_ACK,tcb-〉srcPort,tcb-〉dstPort,tcb->srcAddr,tcb—〉dstAddr); tcb-〉state=ESTABLISHED; return0;}intstud_tcp_send(intsockfd,constunsignedchar*pData,unsignedshortdatalen,intflags){ charbuffer[BUFFER_SIZE]; TCB*tcbPointer=tcbLinkTable; while((tcbPointer!=NULL)&&(tcbPointer->socketfd!=sockfd))tcbPointer=tcbPointer-〉nextTcb;?TCB*tcb=tcbPointer;//找到TCB相應表項 if(tcb==NULL||tcb—〉state!=ESTABLISHED)return—1;?/*發(fā)送DATA報文*/ stud_tcp_output((char*)pDat(yī)a,datalen,PACKET_TYPE_DATA,tcb-〉srcPort,tcb->dstPort,tcb->srcAddr,tcb—〉dstAddr); /*等待接收ACK*/ if(waitIpPacket(buffer,TIMEOUT)==-1)return-1;?if((buffer[13]&0x13)!=0x10)return—1; tcb-〉seq=ntohl(*((UINT32*)(buffer+8))); tcb-〉ack=ntohl(*((UINT32*)(buffer+4)))+1; return0;}intstud_tcp_recv(intsockfd,unsignedchar*pDat(yī)a,unsignedshortdatalen,intflags){ charbuffer[BUFFER_SIZE];?intlen=0; TCB*tcbPointer=tcbLinkTable;?while((tcbPointer!=NULL)&&(tcbPointer—>socketfd!=sockfd))tcbPointer=tcbPointer-〉nextTcb; TCB*tcb=tcbPointer; if(tcb==NULL||tcb->state!=ESTABLISHED)return-1;?/*等待接收數據*/?if((len=waitIpPacket(buffer,TIMEOUT))==—1)return—1; intheader_length=(buffer[12]>〉2)&0x3C; memcpy(pData,buffer+header_length,len-h(huán)eader_length); tcb—>seq=ntohl(*((UINT32*)(buffer+8)));?tcb—〉ack=ntohl(*((UINT32*)(buffer+4)))+(len—header_length); stud_tcp_output(NULL,0,PACKET_TYPE_ACK,tcb-〉srcPort,tcb—〉dstPort,tcb-〉srcAddr,tcb->dstAddr); return0;}intstud_tcp_close(intsockfd){?charbuffer[BUFFER_SIZE];?TCB*pre=NULL;TCB*tcb=tcbLinkTable;?while((tcb!=NULL)&&(tcb-〉socketfd!=sockfd)){?pre=tcb; tcb=tcb—〉nextTcb; }?if(tcb==NULL)return-1;?if(tcb->state!=ESTABLISHED){?if(pre!=NUL

溫馨提示

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

評論

0/150

提交評論