




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
TCP实验报告实验目的1.深入理解TCP原理,掌握连接状态控制、可靠传输等重要机制;2.为应用层提供网络编程接口,即socket接口。实验要求理解TCP的主要原理,针对客户端角色的、“停-等”模式的TCP,设计接收和发送流程。编程实现TCP段的接收流程,重点是段接收的有限状态机编程实现TCP段的发送流程,完成TCP段的封装处理。编程实现客户端Socket接口函数编程实现停-等协议的实现停-等协议主要体现在stud_tcp_send()函数和stud_tcp_recv()和函数中。实现的主要思路是:调用stud_tcp_send()发送一个数据包时,直到收到ack包并把ack交给stud_tcp_input()处理才退出调用stud_tcp_recv()接收一个数据包成功后,紧接着发送一个相应的ack包才退出上述两个设计保证了发送和接收窗口大小为1接收流程的有限状态机首先检查校验和与序号是否正确,只有当这两者都无误之后才进入状态机部分。状态机基于switch结构实现,根据当前TCB的状态分情形讨论状态的变化。处理流程如下发送时的封装和有限状态机查看当前的TCB是否为空,为空则创建当前的TCB封装数据拷贝数据设置源端口和目的端口设置包序列和ack序号设置包头长度设置flag设置windowsize和urgentPointer改变状态变换字节序将字节序从本地序变成网络序各接口函数的实现stud_tcp_socket()stud_tcp_connect()stud_tcp_send()stud_tcp_recv()stud_tcp_close()校验和的计算与IP包的校验类似,但是要求对伪首部进行校验伪首部由以下部分组成:32位IP源地址32位IP目的地址8位填充位(全0)8位协议号16位TCP头部长度实验遇到的问题校验和的计算问题难点在于理解伪首部的结构和作用。停等协议的理解实现接收一个数据包和返回ACK包的绑定;实现发送一个数据包和等待ACK包的绑定源代码#include"sysInclude.h"externvoidtcp_DiscardPkt(char*pBuffer,inttype);//TCP¶ªÆú¶Îº¯Êýexternvoidtcp_sendIpPkt(unsignedchar*pData,UINT16len,unsignedintsrcAddr,unsignedintdstAddr,UINT8 ttl);//IP·Ö×é·¢Ëͺ¯ÊýexternintwaitIpPacket(char*pBuffer,inttimeout);//IPÊý¾Ý·Ö×éÖ÷¶¯½ÓÊÕº¯ÊýexternunsignedintgetIpv4Address();externunsignedintgetServerIpv4Address();typedefstructtcphead{UINT16srcPort;UINT16destPort;UINT32seqNo;UINT32ackNo;UINT8headLen;UINT8flag;UINT16windowsize;UINT16checksum;UINT16urgentPointer;chardata[100];};typedefstructTCB{unsignedintsrcAddr;unsignedintdstAddr;unsignedshortsrcPort;unsignedshortdstPort;unsignedintseq;unsignedintack;intsockfd;BYTEstate;unsignedchar*data;};typedefstructtcb_node{TCB*current;structtcb_node*next;};structtcb_node*tcb_table;structTCB*current_tcb;enumstatus{CLOSED,SYN_SENT,ESTABLISHED,FIN_WAIT1,FIN_WAIT2,TIME_WAIT};intgSrcPort=2008;intgDstPort=2009;intgSeqNum=1234;intgAckNum=0;intsocknum=5;externunsignedintgetchecksum2(tcphead*thead,unsignedintsrcAddr,unsignedintdstAddr,unsignedshortlen,char*data);unsignedintgetchecksum(tcphead*header,unsignedintsrcAddr,unsignedintdstAddr,unsignedshortlen,char*data){unsignedintchecksum=0;checksum+=(srcAddr>>16)+srcAddr&0xffff;checksum+=(dstAddr>>16)+dstAddr&0xffff;checksum+=IPPROTO_TCP;checksum+=0x14;checksum+=ntohs(header->srcPort)+ntohs(header->destPort);checksum+=((header->seqNo)>>16)+(header->seqNo)&0xffff;checksum+=((header->ackNo)>>16)+(header->ackNo)&0xffff;checksum+=((header->headLen)<<8)+header->flag;if(header->flag==PACKET_TYPE_DATA){checksum+=len-0x14;intlength=len;char*p=data;while(length>0){checksum+=(*p)<<8;p++;checksum+=(*p);p++;length=length-2;}}checksum+=ntohs(header->windowsize);checksum+=ntohs(header->urgentPointer); checksum=(checksum>>16)+checksum&0xffff;checksum=(checksum>>16)+checksum&0xffff;checksum=(~checksum)&0xffff; returnchecksum;}intstud_tcp_input(char*pBuffer,unsignedshortlen,unsignedintsrcAddr,unsignedintdstAddr){tcphead*header=(tcphead*)pBuffer;header->seqNo=ntohl(header->seqNo);header->ackNo=ntohl(header->ackNo);if(getchecksum(header,ntohl(srcAddr),ntohl(dstAddr),len,NULL)!=ntohs(header->checksum)){ return-1;}intseqAdd=1;//SYN-SENTFINWAIT1if(current_tcb->state==FIN_WAIT2){seqAdd=0;}elseif(len>20){seqAdd=len-20;}if(header->ackNo!=(current_tcb->seq+seqAdd)){tcp_DiscardPkt(pBuffer,STUD_TCP_TEST_SEQNO_ERROR);return-1;}switch(current_tcb->state){caseSYN_SENT:if(header->flag==PACKET_TYPE_SYN_ACK){current_tcb->state=ESTABLISHED;current_tcb->ack=header->seqNo+1;current_tcb->seq=header->ackNo;stud_tcp_output(NULL,0,PACKET_TYPE_ACK,current_tcb->srcPort,current_tcb->dstPort,ntohl(srcAddr),ntohl(dstAddr));break;}else{return-1;}caseESTABLISHED:if(header->flag==PACKET_TYPE_ACK){if(len>20){current_tcb->ack=header->seqNo+len-20;current_tcb->seq=header->ackNo;break;}elseif(len==20){current_tcb->ack=header->seqNo+1;current_tcb->seq=header->ackNo;break;}elsereturn-1;}elsereturn-1;caseFIN_WAIT1:if(header->flag==PACKET_TYPE_ACK){current_tcb->ack=header->seqNo+1;current_tcb->seq=header->ackNo;current_tcb->state=FIN_WAIT2;break;}else{return-1;}caseFIN_WAIT2:if(header->flag==PACKET_TYPE_FIN_ACK){current_tcb->state=TIME_WAIT;stud_tcp_output(NULL,0,PACKET_TYPE_ACK,current_tcb->srcPort,current_tcb->dstPort,ntohl(srcAddr),ntohl(dstAddr));break;}else{return-1;}default:return-1;}return0;}voidstud_tcp_output(char*pData,unsignedshortlen,unsignedcharflag,unsignedshortsrcPort,unsignedshortdstPort,unsignedintsrcAddr,unsignedintdstAddr){if(current_tcb==NULL){current_tcb=newTCB;current_tcb->seq=gSeqNum;current_tcb->ack=gAckNum;current_tcb->srcPort=srcPort;current_tcb->dstPort=dstPort;current_tcb->srcAddr=srcAddr;current_tcb->dstAddr=dstAddr;current_tcb->state=CLOSED;}tcphead*thead=newtcphead;for(inti=0;i<len;i++){thead->data[i]=pData[i];}thead->srcPort=srcPort;thead->destPort=dstPort;thead->seqNo=current_tcb->seq;thead->ackNo=current_tcb->ack;thead->headLen=0x50;thead->flag=flag;thead->windowsize=1;thead->urgentPointer=0;switch(current_tcb->state){caseCLOSED:if(flag==PACKET_TYPE_SYN){current_tcb->state=SYN_SENT;}elsereturn;break;caseESTABLISHED:if(flag==PACKET_TYPE_FIN_ACK){current_tcb->state=FIN_WAIT1;break;}elseif(flag==PACKET_TYPE_DATA||flag==PACKET_TYPE_ACK){break;}elsereturn;break;defalut:return;}thead->checksum=ntohs(getchecksum2(thead,srcAddr,dstAddr,len,pData));thead->srcPort=ntohs(thead->srcPort);thead->destPort=ntohs(thead->destPort);thead->seqNo=ntohl(thead->seqNo);thead->ackNo=ntohl(thead->ackNo);thead->windowsize=ntohs(thead->windowsize);thead->urgentPointer=ntohs(thead->urgentPointer);tcp_sendIpPkt((unsignedchar*)thead,20+len,current_tcb->srcAddr,current_tcb->dstAddr,60);}intstud_tcp_socket(intdomain,inttype,intprotocol){if(domain!=AF_INET||type!=SOCK_STREAM||protocol!=IPPROTO_TCP)return-1;current_tcb=newTCB;if(tcb_table==NULL){tcb_table=newtcb_node;tcb_table->current=current_tcb;tcb_table->next=NULL;}else{tcb_node*head=tcb_table;while(head->next!=NULL){head=head->next;}head->next=newtcb_node;head->next->current=current_tcb;head->next->next=NULL;}current_tcb->sockfd=socknum++;current_tcb->srcPort=gSrcPort++;current_tcb->seq=gSeqNum++;current_tcb->ack=gAckNum;current_tcb->state=CLOSED;returncurrent_tcb->sockfd;}intgetSockfd(intsockfd){tcb_node*current_p=tcb_table;while(current_tcb!=NULL&¤t_p->current!=NULL){if(current_p->current->sockfd==sockfd){current_tcb=current_p->current;return0;break;}current_p=current_p->next;}if(current_p==NULL)return-1;}intstud_tcp_connect(intsockfd,structsockaddr_in*addr,intaddrlen){if(getSockfd(sockfd)==-1)return-1; UINT32srcAddr=getIpv4Address();UINT32dstAddr=htonl(addr->sin_addr.s_addr);current_tcb->srcAddr=srcAddr;current_tcb->dstAddr=dstAddr;current_tcb->dstPort=ntohs(addr->sin_port);current_tcb->state=SYN_SENT;stud_tcp_output(NULL,0,PACKET_TYPE_SYN,current_tcb->srcPort,current_tcb->dstPort,srcAddr,dstAddr);tcphead*receive=newtcphead;intres=-1;while(res==-1){res=waitIpPacket((char*)receive,5000);}stud_tcp_input((char*)receive,20,ntohl(current_tcb->srcAddr),ntohl(current_tcb->dstAddr));return0;}intstud_tcp_send(intsockfd,constunsignedchar*pData,unsignedshortdatalen,intflags){if(getSockfd(sockfd)==-1)return-1;if(current_tcb->state!=ESTABLISHED)return-1;else{UINT32srcAddr=getIpv4Address();UINT32dstAddr=current_tcb->dstAddr;current_tcb->data=newunsignedchar(datalen);strcpy((char*)current_tcb->data,(char*)pData);stud_tcp_output((char*)current_tcb->data,datalen,PACKET_TYPE_DATA,current_tcb->srcPort,current_tcb->dstPort,srcAddr,dstAddr);tcphead*receive=newtcphead;intres=-1;while(res==-1){res=waitIpPacket((char*)receive,5000);}stud_tcp_input((char*)receive,datalen+20,ntohl(current_tcb->srcAddr),ntohl(current_tcb->dstAddr));} return0;}intstud_tcp_recv(intsockfd,unsignedchar*pData,unsignedshortdatalen,intflags){if(getSockfd(sockfd)==-1)return-1;if(current_tcb->state!=ESTABLISHED)return-1;else{UINT32srcAddr=getIpv4Address();UINT32dstAddr=current_tcb->dstAddr;tcphead*receive=newtcphead;intres=-1;while(res==-1) {res=waitIpPacket((char*)receive,5000);}strcpy((char*)pData,(char*)receive->data);datalen=sizeof(pData);stud_tcp_output(NULL,0,PACKET_TYPE_ACK,current_tcb->srcPort,current_tcb->dstPort,srcAddr,dstAddr);}}intstud_tcp_close(intsockfd){tcb_node*current_p=tcb_table;tcb_node*preCurrent=current_p;while(current_p!=NULL&¤t_p->current!=NULL){if(current_p->current->sockfd==sockfd){current_tcb=current_p->current;break;}preCurrent=current_p;current_p=current_p->next;}if(current_p==NULL)return-1;UINT32srcAddr=getIpv4Address();UINT32dstAddr=current_tcb->dstAddr;if(current_tcb->state!=ESTABLISHED){if(current_p!=preCurrent){preCurrent->next=current_p->next;deletecurrent_p;}elsedeletecurrent_tcb;current_tcb=NULL; return-1;}else{stud_tcp_output(NULL,0,PACKET_TYPE_FIN_ACK,current_tcb->srcPort,current_tcb->dstPort,srcAddr,dstAddr);current_tcb->state=FIN_WAIT1; tcphead*receive=newtcphead;intres=-1;while(res==-1){res=waitIpPacket((char*)receive,5000);}stud_tcp_input((char*)receive,20,ntohl(current_tcb->srcAddr),ntohl(current_tcb->dstAddr));//ackres=-1;while(res==-1){
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 考试心态调整特许金融分析师考试试题及答案
- 证券投资中的人机结合分析试题及答案
- 2025年财务报告标准变动试题及答案
- 2025年CFA考试资本市场操作试题及答案
- 微生物分析报告的撰写技巧试题及答案
- 2024年项目管理新挑战及应对策略试题及答案
- 预备工作2025年证券从业资格证试题及答案
- 矿山安全应急预案与演练-石墨滑石考核试卷
- 2025年审计审查重点试题及答案
- 矿山环境管理与生态断层监测考核试卷
- 金属废料资源化利用
- 2023装配式建筑标准化产品系列图集(预制内墙条板)SJT 03-2023
- 远动设备故障处理措施
- 《真空热处理炉》课件
- 医院检验科实验室生物安全管理手册
- 企业财务管理优化方案
- NB-T 47013.2-2015 承压设备无损检测 第2部分-射线检测
- 实用版建筑工程工程合同模板
- 新型马路划线机设计
- 《儿科学》课件第9章第九节 腹泻病
- 小学生主题班会 拒绝作弊+诚信考试+宣传教育 课件(共28张PPT)
评论
0/150
提交评论