发送TCP数据包设计题4.docx
- 文档编号:6663605
- 上传时间:2023-05-10
- 格式:DOCX
- 页数:14
- 大小:172.03KB
发送TCP数据包设计题4.docx
《发送TCP数据包设计题4.docx》由会员分享,可在线阅读,更多相关《发送TCP数据包设计题4.docx(14页珍藏版)》请在冰点文库上搜索。
发送TCP数据包设计题4
设计题4:
发送TCP数据包
本设计的目的是填充一个TCP数据包,并发送给目的主机。
1)以命令行形式运行:
SendTCPsource_ipsource_portdest_ipdest_portData
其中SendTCP为程序名,source_ip、source_port、dest_ip和dest_port分别为源IP地址、目的IP地址、源端口和目的端口,Data为数据字段。
2)其他的TCP头部参数请自行设定。
3)数据字段为“Thisismyhomeworkofnetwork,Iamveryhappy!
”。
4)成功发送后在屏幕上输出“sendOK”。
引言:
TCP作用
TCP建立连接时的三次握手
在因特网协议族(Internetprotocolsuite)四层协议中,TCP层是位于IP层之上,应用层之下的传输层。
不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换。
应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分割成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传送单元(MTU)的限制)。
之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。
TCP为了保证不发生丢包,就给每个字节一个序号,同时序号也保证了传送到接收端实体的包的按序接收。
然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算和校验。
首先,TCP建立连接之后,通信双方都同时可以进行数据的传输,其次,它是全双工的;在保证可靠性上,采用超时重传和捎带确认机制。
在流量控制上,采用滑动窗口协议,协议中规定,对于窗口内未经确认的分组需要重传。
在拥塞控制上,采用广受好评的TCP拥塞控制算法(也称AIMD算法),该算法主要包括三个主要部分:
1,加性增、乘性减;2,慢启动;3,对超时事件做出反应。
具体设计:
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位服务类型TOS
USHORTtotal_len;//16位总长度(字节)
USHORTident;//16位标识
USHORTfrag_and_flags;//3位标志位
UCHARttl;//8位生存时间TTL
UCHARproto;//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(size>1)
{
cksum+=*buffer++;
size-=sizeof(USHORT);
}
if(size)
{
cksum+=*(UCHAR*)buffer;
}
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return(USHORT)(~cksum);
}
4.流程图
源程序:
SENDTCP:
#include
#include
#include
#include
#include
#include
#include
#include
#pragmacomment(lib,"ws2_32.lib")
#defineIPVER4
#defineMAX_BUFF_LEN65500
typedefstructip_hdr
{
UCHARh_verlen;
UCHARtos;
USHORTtotal_len;
USHORTident;
USHORTfrag_and_flags;
UCHARttl;
UCHARproto;
USHORTchecksum;
ULONGsourceIP;
ULONGdestIP;
}
IP_HEADER;
typedefstructtsd_hdr
{
ULONGsaddr;
ULONGdaddr;
UCHARmbz;
UCHARptcl;
USHORTtcpl;
}
PSD_HEADER;
typedefstructtcp_hdr
{
USHORTth_sport;
USHORTth_dport;
ULONGth_seq;
ULONGth_ack;
UCHARth_lenres;
UCHARth_flag;
USHORTth_win;
USHORTth_sum;
USHORTth_urp;
}
TCP_HEADER;
USHORTchecksum(USHORT*buffer,intsize)
{
unsignedlongcksum=0;
while(size>1)
{
cksum+=*buffer++;
size-=sizeof(USHORT);
}
if(size)
{
cksum+=*(UCHAR*)buffer;
}
cksum=(cksum>>16)+(cksum&0xffff);
cksum+=(cksum>>16);
return(USHORT)(~cksum);
}
intmain(intargc,char*argv[])
{
WSADATAWSAData;
SOCKETsock;
IP_HEADERipHeader;
TCP_HEADERtcpHeader;
PSD_HEADERpsdHeader;
charSendto_Buff[MAX_BUFF_LEN];
unsignedshortcheck_Buff[MAX_BUFF_LEN];
constchartcp_send_data[]={"Thisismyhomeworkofnetwort,Iamhappy!
"};
BOOLflag;
intrect,nTimeOver;
if(argc!
=5)
{
printf("Useage:
SendTcpsoruce_ipsource_portdest_ipdest_port\n");
returnfalse;
}
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;
}
ipHeader.h_verlen=(IPVER<<4|sizeof(ipHeader)/sizeof(unsignedlong));
ipHeader.tos=(UCHAR)0;
ipHeader.total_len=htons((unsignedshort)sizeof(ipHeader)+sizeof(tcpHeader)+sizeof(tcp_send_data));
ipHeader.ident=0;
ipHeader.frag_and_flags=0;
ipHeader.ttl=128;
ipHeader.proto=IPPROTO_UDP;
ipHeader.checksum=0;
ipHeader.sourceIP=inet_addr(argv[1]);
ipHeader.destIP=inet_addr(argv[3]);
memset(check_Buff,0,MAX_BUFF_LEN);
memcpy(check_Buff,&ipHeader,sizeof(IP_HEADER));
ipHeader.checksum=checksum(check_Buff,sizeof(IP_HEADER));
psdHeader.saddr=ipHeader.sourceIP;
psdHeader.daddr=ipHeader.destIP;
psdHeader.mbz=0;
psdHeader.ptcl=ipHeader.proto;
psdHeader.tcpl=htons(sizeof(TCP_HEADER)+sizeof(tcp_send_data));
tcpHeader.th_dport=htons(atoi(argv[4]));
tcpHeader.th_sport=htons(atoi(argv[2]));
tcpHeader.th_seq=0;
tcpHeader.th_ack=0;
tcpHeader.th_lenres=(sizeof(tcpHeader)/sizeof(unsignedlong)<<4|0);
tcpHeader.th_flag=2;
tcpHeader.th_win=htons((unsignedshort)16384);
tcpHeader.th_urp=0;
tcpHeader.th_sum=0;
memset(check_Buff,0,MAX_BUFF_LEN);
memcpy(check_Buff,&psdHeader,sizeof(psdHeader));
memcpy(check_Buff+sizeof(psdHeader),&tcpHeader,sizeof(tcpHeader));
memcpy(check_Buff+sizeof(PSD_HEADER)+sizeof(TCP_HEADER),tcp_send_data,sizeof(tcp_send_data));
tcpHeader.th_sum=checksum(check_Buff,sizeof(PSD_HEADER)+sizeof(TCP_HEADER)+sizeof(tcp_send_data));
memset(Sendto_Buff,0,MAX_BUFF_LEN);
memcpy(Sendto_Buff,&ipHeader,sizeof(IP_HEADER));
memcpy(Sendto_Buff+sizeof(IP_HEADER),&tcpHeader,sizeof(TCP_HEADER));
memcpy(Sendto_Buff+sizeof(IP_HEADER)+sizeof(TCP_HEADER),tcp_send_data,sizeof(tcp_send_data));
intdatasize=sizeof(IP_HEADER)+sizeof(TCP_HEADER)+sizeof(tcp_send_data);
SOCKADDR_INdest;
memset(&dest,0,sizeof(dest));
dest.sin_family=AF_INET;
dest.sin_addr.s_addr=inet_addr(argv[3]);
dest.sin_port=htons(atoi(argv[4]));
rect=sendto(sock,Sendto_Buff,datasize,0,(structsockaddr*)&dest,sizeof(dest));
if(rect==SOCKET_ERROR)
{
printf("senderror!
:
%d\n",WSAGetLastError());
returnfalse;
}
else
printf("sendok!
\n");
closesocket(sock);
WSACleanup();
return1;
}
SER:
#include
#include
#include
usingnamespacestd;
#pragmacomment(lib,"WS2_32.lib")
intmain()
{
WSADATAwsaData;
WORDsockVersion=MAKEWORD(2,2);
SOCKETsListen=0;
sockaddr_insin={0};
sockaddr_inremoteAddr={0};
charszText[]="TCPServerDemo";
intnAddrLen=0;
nAddrLen=sizeof(sockaddr_in);
sin.sin_port=htons(4567);
sin.sin_family=AF_INET;
sin.sin_addr.S_un.S_addr=INADDR_ANY;
if(WSAStartup(sockVersion,&wsaData)!
=0)
{
cout<<"initlizationfailed!
"< exit(0); } sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(bind(sListen,(LPSOCKADDR)&sin,sizeof(sin))==SOCKET_ERROR) { cout<<"bindfailed! "< return0; } if(listen(sListen,2)==SOCKET_ERROR){ cout<<"listenfailed! "< return0; } SOCKETsClient=INADDR_ANY; while(true) { sClient=accept(sListen,(SOCKADDR*)&remoteAddr,&nAddrLen); if(sClient==INVALID_SOCKET) { cout<<"acceptfailed! "< continue; } send(sClient,szText,strlen(szText),0); closesocket(sClient); } closesocket(sListen); WSACleanup(); } TCPCLIENT: #include #include #include usingnamespacestd; #pragmacomment(lib,"WS2_32.lib") intmain() { WSADATAwsaData; WORDsockVersion=MAKEWORD(2,2); SOCKETsock=0; if(WSAStartup(sockVersion,&wsaData)! =0) { cout<<"initlizationfailed! "< exit(0); } sock=: : socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(sock==INVALID_SOCKET) { cout<<"failedsocket! "< return0; } sockaddr_insin; sin.sin_family=AF_INET; sin.sin_port=htons(4567); sin.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); if(connect(sock,(sockaddr*)&sin,sizeof(sockaddr))==-1) { cout<<"connectfailed! "< return0; } charbuffer[256]="\0"; intnRecv=0; nRecv=recv(sock,buffer,256,0); if(nRecv>0) { buffer[nRecv]='\0'; cout<<"reveivedata: "< } closesocket(sock); WSACleanup(); }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 发送 TCP 数据包 设计