您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > TCP数据包的发送和接收设计报告
湖北工业大学课程设计报告设计题目:TCP数据包的发送和接收专业:计算机科学与技术班级:10计科2班学号:1010311211姓名:吕红杰指导老师:涂军一.设计题目发送和接收TCP数据包二.设计要求1.正确理解题意;2.具有良好的编程规范和适当的注释;3.有详细的文档,文档中应包括设计题目涉及的基础知识、设计思路、程序流程图、程序清单、开发中遇到的问题及解决方法、设计中待解决的问题及改进方向。三.需求分析TCP是一种面向连接的、可靠的传输层协议。TCP协议工作在网络层IP协议的基础上。本课程设计的目的是设计一个发送和接收TCP数据包的程序,其功能是填充一个TCP数据包,发送给目的主机,并在目的主机接收此TCP数据包,将数据字段显示显示在标准输出上。四.具体设计1.创建一个原始套接字,并设置IP头选项SOCKETsock;sock=socket(AF_INET,SOCK_RAW,IPPROTO_IP);或者:sock=WSASoccket(AF_INET,SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);这里,设置了SOCK_RAW标志,表示我们声明的是一个原始套接字类型。为使用发送接收超时设置,必须将标志位置位置为WSA_FLAG_OVERLAPPED。在本课程设计中,发送TCP包时隐藏了自己的IP地址,因此我们要自己填充IP头,设置IP头操作选项。其中flag设置为ture,并设定IP_HDRINCL选项,表明自己来构造IP头。setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&Flag,sizeof(Flag));inttimeout=1000;setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout));在这里我们使用基本套接字SOL_SOCKET,设置SO_SNDTIMEO表示使用发送超时设置,超时时间设置为1000ms。2.构造IP头和TCP头这里,IP头和TCP头以及TCP伪部的构造请参考下面它们的数据结构。typedefstruct_iphdr//定义IP首部{UCHARh_lenver;//4位首部长度+4位IP版本号UCHARtos;//8位服务类型TOSUSHORTtotal_len;//16位总长度(字节)USHORTident;//16位标识USHORTfrag_and_flags;//3位标志位UCHARttl;//8位生存时间TTLUCHARproto;//8位协议(TCP,UDP或其他)USHORTchecksum;//16位IP首部校验和ULONGsourceIP;//32位源IP地址ULONGdestIP;//32位目的IP地址}IP_HEADER;typedefstructpsd_hdr//定义TCP伪首部{ULONGsaddr;//源地址ULONGdaddr;//目的地址UCHARmbz;//没用UCHARptcl;//协议类型USHORTtcpl;//TCP长度}PSD_HEADER;typedefstruct_tcphdr//定义TCP首部{USHORTth_sport;//16位源端口USHORTth_dport;//16位目的端口ULONGth_seq;//32位序列号ULONGth_ack;//32位确认号UCHARth_lenres;//4位首部长度/6位保留字UCHARth_flag;//6位标志位USHORTth_win;//16位窗口大小USHORTth_sum;//16位校验和USHORTth_urp;//16位紧急数据偏移量}TCP_HEADER;3.计算校验和的子函数在填充数据包的过程中,需要调用计算校验和的函数checksum两次,分别用于校验IP头和TCP头部(加上伪头部),其实现代码如下:USHORTchecksum(USHORT*buffer,intsize){unsignedlongcksum=0;while(size1){cksum+=*buffer++;size-=sizeof(USHORT);}if(size){cksum+=*(UCHAR*)buffer;}cksum=(cksum16)+(cksum&0xffff);cksum+=(cksum16);return(USHORT)(~cksum);}4.流程图开始构造原始套接字并初始化填充IP首部计算IP首部校验和构造TCP伪首部填充TCP首部计算TCP首部校验和填充发送缓冲区填入目的地址发送数据包结束五.实验内容1.先用vc++编译运行程序代码2.用命令指示符运行Debug下的sendTCP3.输入源ip和端口及目的ip和端口4.输入发送内容5.发送完成六.附代码#includestdio.h#includestring.h#includewinsock2.h#includews2tcpip.h#includetime.h#includewindows.h#includestdlib.h#includeiostream.h#pragmacomment(lib,ws2_32.lib)#defineIPVER4//IP协议预定#defineMAX_BUFF_LEN65500//发送缓冲区最大值typedefstructip_hdr//定义IP首部{UCHARh_verlen;//4位首部长度,4位IP版本号UCHARtos;//8位服务类型TOSUSHORTtotal_len;//16位总长度(字节)USHORTident;//16位标识USHORTfrag_and_flags;//3位标志位UCHARttl;//8位生存时间TTLUCHARproto;//8位协议(TCP,UDP或其他)USHORTchecksum;//16位IP首部校验和ULONGsourceIP;//32位源IP地址ULONGdestIP;//32位目的IP地址}IP_HEADER;typedefstructtsd_hdr//定义TCP伪首部{ULONGsaddr;//源地址ULONGdaddr;//目的地址UCHARmbz;//没用UCHARptcl;//协议类型USHORTtcpl;//TCP长度}PSD_HEADER;typedefstructtcp_hdr//定义TCP首部{USHORTth_sport;//16位源端口USHORTth_dport;//16位目的端口ULONGth_seq;//32位序列号ULONGth_ack;//32位确认号UCHARth_lenres;//4位首部长度/6位保留字UCHARth_flag;//6位标志位USHORTth_win;//16位窗口大小USHORTth_sum;//16位校验和USHORTth_urp;//16位紧急数据偏移量}TCP_HEADER;//CheckSum:计算校验和的子函数USHORTchecksum(USHORT*buffer,intsize){unsignedlongcksum=0;while(size1){cksum+=*buffer++;size-=sizeof(USHORT);}if(size){cksum+=*(UCHAR*)buffer;}cksum=(cksum16)+(cksum&0xffff);cksum+=(cksum16);return(USHORT)(~cksum);}intReadData(char*str,intmaxlen){intreadlen=0;charch=NULL;if(str==NULL||maxlen=0){printf(ReadDataError!!!\n);return0;//failed}printf(InputData(EndByCtrl+Z):\n);while(maxlen){ch=getchar();if(ch==EOF)break;str[readlen++]=ch;maxlen--;}str[readlen]=NULL;returnreadlen;}intmain(intargc,char*argv[]){WSADATAWSAData;SOCKETsock;IP_HEADERipHeader;TCP_HEADERtcpHeader;PSD_HEADERpsdHeader;charSendto_Buff[MAX_BUFF_LEN];//发送缓冲区unsignedshortcheck_Buff[MAX_BUFF_LEN];//检验和缓冲区chartcp_send_data[1000];intread_data_len=0;BOOLflag;intrect,nTimeOver;if(argc!=5){printf(Usage:SendTcpsoruce_ipsource_portdest_ipdest_port\n);returnfalse;}read_data_len=ReadData(tcp_send_data,1000);if(read_data_len=0)return1;if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0){printf(WSAStartupError!\n);returnfalse;}if((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET){printf(SocketSetupError!\n);returnfalse;}flag=true;if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag))==SOCKET_ERROR){printf(setsockoptIP_HDRINCLerror!\n);returnfalse;}nTimeOver=1000;if(setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char*)&nTimeOver,sizeof(nTimeOver))==SOCKET_ERROR){printf(setsockoptSO_SNDTIMEOerror!\n);returnfalse;}//填充IP首部ipHeader.h_verlen=(IPVER4|sizeof(ipHeader)/sizeof(unsignedlong));ipHeader.tos=(UCHAR)0;ipHeader.total_len=htons((unsignedshort)sizeof(ipHeader)+sizeof(tcpHeader)+read_data_len);ipHeader.ident=0;//16位标识ipHeader.frag_and_flags=0;//3位标志位ipHeader.ttl=128;//8位生存时间ipHeader.proto=IPPROTO_TCP;//协议类型ipHeader.checksum=0;//检验和暂时为0ipHeader.sourceIP=inet_addr(argv[1]);//32位源IP地址ipHeader.destIP=inet_addr(argv[3]);//32位目的IP地址//计算IP头部检验和memset(check_Buff,0,MAX_BUFF_LEN);memcpy(check_Buff,&ipHeader,sizeof(IP_HEADER));ipHeader.checksum=checksum(check_Buff,sizeof(IP_HEADER));//构造TCP伪首部psdHeader.saddr=ipHeader.sourceIP;psdHeader.daddr=ipHeader.de
本文标题:TCP数据包的发送和接收设计报告
链接地址:https://www.777doc.com/doc-7351499 .html