计算机网络 课程设计 发送TCP数据包_tcp数据包发送和接收

2020-02-27 其他范文 下载本文

计算机网络 课程设计 发送TCP数据包由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“tcp数据包发送和接收”。

课设名称:发送TCP数据包

班级:

学号:

姓名:

指导老师: 日期: 2012.6.15

计算机网络课程设计报告

目录

一.设计题目与要求........................................................................................................2

1.设计题目................................................................................................................2

2.设计要求................................................................................................................2

二.需求分析...................................................................................................................2三.详细设计...................................................................................................................2

1.创建一个原始套接字,并设置IP头选项.................................................................3

2.构造IP头和TCP头...............................................................................................3

3.计算校验和的子函数..............................................................................................4

4.流程图...................................................................................................................6

四.调试分析...................................................................................................................7

五.运行结果...................................................................................................................7

六.总结..........................................................................................................................8

七.源程序......................................................................................................................9

发送TCP数据包

一.设计题目与要求

1.设计题目

发送TCP数据包 2.设计要求

本设计的功能是填充一个TCP数据包,并发送给目的主机。

1)以命令行形式运行:TCP source_ip source_port dest_ip dest_port,其中SendTCP是程序名,source_ip为源端IP地址,source_port为源端口号,dest_ip为目的地址,dest_port为目的端口号。

2)其他的TCP头部参数请自行设定。3)数据字段为“hello”。

4)成功发送后在屏幕上输出“send OK”。

二.需求分析

1.本程序需完成发送一个TCP数据包给目的主机

2.程序的输入:TCP source_ip source_port dest_ip dest_port,然后根据提示输入要发送的数据,回车即可。

3.程序的输出:Send OK!

4.测试数据 TCP 192.168.1.100 200 192.168.1.101 200

三.详细设计

本课程设计的目标是发送一个TCP数据包,可以利用原始套接字来完成这个工作。整个程序由初始化原始套接字和发送TCP数据包两个部分组成。

2发送TCP数据包

1.创建一个原始套接字,并设置IP头选项

SOCKET sock;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));int timeout=1000; setsockopt(sock, sizeof(timeout));在这里我们使用基本套接字SOL_SOCKET,设置SO_SNDTIMEO表示使用发送超时设置,超时时间设置为1000ms。2.构造IP头和TCP头

这里,IP头和TCP头以及TCP伪部的构造请参考下面它们的数据结构。

typedef struct _iphdr //定义IP首部 { UCHAR h_lenver;//4位首部长度+4位IP版本号 UCHAR tos;//8位服务类型TOS

USHORT total_len;//16位总长度(字节)USHORT ident;//16位标识

USHORT frag_and_flags;//3位标志位 UCHAR ttl;//8位生存时间 TTL

UCHAR proto;//8位协议(TCP, UDP 或其他)

SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,3发送TCP数据包

USHORT checksum;//16位IP首部校验和 ULONG sourceIP;//32位源IP地址

ULONG destIP;//32位目的IP地址

}IP_HEADER;typedef struct psd_hdr //定义TCP伪首部 { ULONG saddr;ULONG daddr;//源地址 //目的地址

UCHAR mbz;//没用 UCHAR ptcl;

USHORT tcpl;//协议类型 //TCP长度

}PSD_HEADER;typedef struct _tcphdr //定义TCP首部 { USHORT th_sport;//16位源端口 USHORT th_dport;//16位目的端口 ULONG th_seq;//32位序列号 ULONG th_ack;//32位确认号

UCHAR th_lenres;//4位首部长度/6位保留字 UCHAR th_flag;//6位标志位 USHORT th_win;//16位窗口大小 USHORT th_sum;//16位校验和 USHORT th_urp;//16位紧急数据偏移量

}TCP_HEADER;

3.计算校验和的子函数

在填充数据包的过程中,需要调用计算校验和的函数checksum两次,分别用于校验IP头和TCP头部(加上伪头部),其实现代码如下:

USHORT checksum(USHORT *buffer, int size)

4发送TCP数据包

{ unsigned long cksum=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);}

5发送TCP数据包

4.流程图

开始构造原始套接字并初始化填充IP首部计算IP首部校验和构造TCP伪首部填充TCP首部计算TCP首部校验和填充发送缓冲区填入目的地址发送数据包结束

6发送TCP数据包

四.调试分析

本程序流程简单,调试过程中没有出现大的问题。

调试过程中没有出现重大的语法错误,主要是运行的结果不理想,和预期的结果有差距。填充数据包的程序部分是不容易出错的。至于数据包的发送,由于是利用函数sendto()来实现的,而sendto()是面向UDP的,将协议类型修改为UDP(Header.proto=IPPROTO_UDP;)后,调试运行成功,问题得到解决。

调试时,要添加 #include #include #pragma comment(lib,“ws2_32.lib”)不然编译出错。

五.运行结果

1.输入:TCP 192.168.1.100 200 192.168.1.101 200

7发送TCP数据包

2.输入要发送的字符串:“hello”按Ctrl+Z发送

六.总结

通过本次课程设计,我对发送TCP数据包的原理有了一定的了解。理解了TCP数据报的报文格式、TCP连接时的三次握手和TCP连接结束时的四次握手的过程及它们的作用。此外,在设计过程中,通过查阅资料,也让我对TCP的三大特点(流量控制、差错控制、拥塞控制)有了认识。,在课程设计过程中,由于编程知识的欠缺,使我在课程设计过程中不是很顺利,编程知识的欠缺是我的最大障碍,不过,这也给了我动力,我会努力去学好编程的相关知识,为以后的学习和工作打下基础。最后,感谢老师安排了此次课程设计。

发送TCP数据包

七.源程序

#include #include #include #include #include #include #include #include #pragma comment(lib,“ws2_32.lib”)

#define IPVER 4 //IP协议预定 #define MAX_BUFF_LEN 65500 //发送缓冲区最大值

typedef struct ip_hdr //定义IP首部 {

UCHAR h_verlen;//4位首部长度,4位IP版本号 UCHAR tos;//8位服务类型TOS USHORT total_len;//16位总长度(字节)USHORT ident;//16位标识 USHORT frag_and_flags;//3位标志位 UCHAR ttl;//8位生存时间 TTL UCHAR proto;//8位协议(TCP, UDP 或其他)USHORT checksum;//16位IP首部校验和 ULONG sourceIP;//32位源IP地址 ULONG destIP;//32位目的IP地址

发送TCP数据包

}IP_HEADER;

typedef struct tsd_hdr //定义TCP伪首部 {

ULONG saddr;//源地址 ULONG daddr;//目的地址 UCHAR mbz;//没用 UCHAR ptcl;//协议类型 USHORT tcpl;//TCP长度

}PSD_HEADER;

typedef struct tcp_hdr //定义TCP首部 {

USHORT th_sport;//16位源端口 USHORT th_dport;//16位目的端口 ULONG th_seq;//32位序列号 ULONG th_ack;//32位确认号

UCHAR th_lenres;//4位首部长度/6位保留字 UCHAR th_flag;//6位标志位 USHORT th_win;//16位窗口大小 USHORT th_sum;//16位校验和

USHORT th_urp;//16位紧急数据偏移量

}TCP_HEADER;

//CheckSum:计算校验和的子函数

USHORT checksum(USHORT *buffer, int size){ unsigned long cksum=0;while(size >1)

发送TCP数据包

{ cksum+=*buffer++;size-=sizeof(USHORT);} if(size){ cksum += *(UCHAR*)buffer;} cksum =(cksum >> 16)+(cksum & 0xffff);cksum +=(cksum >>16);return(USHORT)(~cksum);}

int ReadData(char *str,int maxlen){ int readlen=0;char ch=NULL;if(str==NULL||maxlen

printf(“ReadData Error!!n”);

return 0;//failed } printf(“Input Data(End By Ctrl+Z): n”);while(maxlen){

ch=getchar();

if(ch==EOF)break;

str[readlen++]=ch;maxlen--;

发送TCP数据包

} } str[readlen]=NULL;return readlen;int main(int argc, char* argv[]){ WSADATA WSAData;SOCKET sock;

IP_HEADER ipHeader;TCP_HEADER tcpHeader;PSD_HEADER psdHeader;

char Sendto_Buff[MAX_BUFF_LEN];//发送缓冲区

unsigned short check_Buff[MAX_BUFF_LEN];//检验和缓冲区 char tcp_send_data[1000];

BOOL flag;int rect,nTimeOver;if(argc!= 5){ printf(“Usage: SendTcp soruce_ip source_port dest_ip dest_port n”);return false;} read_data_len=ReadData(tcp_send_data,1000);int read_data_len=0;

发送TCP数据包

if(read_data_len

if(WSAStartup(MAKEWORD(2,2), &WSAData)!=0){ printf(“WSAStartup Error!n”);return false;} if((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0, WSA_FLAG_OVERLAPPED))==INVALID_SOCKET){ printf(“Socket Setup Error!n”);return false;} flag=true;if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag))==SOCKET_ERROR){ printf(“setsockopt IP_HDRINCL error!n”);return false;} nTimeOver=1000;if(setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,(char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR){ printf(“setsockopt SO_SNDTIMEO error!n”);return false;}

发送TCP数据包

//填充IP首部

ipHeader.h_verlen=(IPVER

//计算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.destIP;psdHeader.mbz=0;psdHeader.ptcl=ipHeader.proto;psdHeader.tcpl=htons(sizeof(TCP_HEADER)+read_data_len);

//填充TCP首部

tcpHeader.th_dport=htons(atoi(argv[4]));//16位目的端口号 tcpHeader.th_sport=htons(atoi(argv[2]));//16位源端口号

发送TCP数据包

tcpHeader.th_seq=0;//SYN序列号 tcpHeader.th_ack=0;//ACK序列号置为0 //TCP长度和保留位

tcpHeader.th_lenres=(sizeof(tcpHeader)/sizeof(unsigned long)

tcpHeader.th_win=htons((unsigned short)16384);//窗口大小 tcpHeader.th_urp=0;//偏移大小 tcpHeader.th_sum=0;//检验和暂时填为0

//计算TCP校验和

memset(check_Buff,0,MAX_BUFF_LEN);memcpy(check_Buff,&psdHeader,sizeof(psdHeader));

memcpy(check_Buff+sizeof(psdHeader),&tcpHeader,sizeof(tcpHeader));

//填充发送缓冲区

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(check_Buff+sizeof(PSD_HEADER)+sizeof(TCP_HEADER), tcp_send_data,read_data_len);tcpHeader.th_sum=checksum(check_Buff,sizeof(PSD_HEADER)+ sizeof(TCP_HEADER)+read_data_len);memcpy(Sendto_Buff+sizeof(IP_HEADER)+sizeof(TCP_HEADER), tcp_send_data,read_data_len);

发送TCP数据包

int datasize=sizeof(IP_HEADER)+sizeof(TCP_HEADER)+read_data_len;//发送数据报的目的地址 SOCKADDR_IN dest;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,(struct sockaddr*)&dest, sizeof(dest));if(rect==SOCKET_ERROR){ printf(“send error!:%dn”,WSAGetLastError());return false;} else

closesocket(sock);WSACleanup();return 1;} printf(“nsend ok!n”);

《计算机网络 课程设计 发送TCP数据包.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
计算机网络 课程设计 发送TCP数据包
点击下载文档
相关专题 tcp数据包发送和接收 计算机网络 数据包 课程设计 tcp数据包发送和接收 计算机网络 数据包 课程设计
[其他范文]相关推荐
    [其他范文]热门文章
      下载全文