网络课程设计任务书完整.docx
《网络课程设计任务书完整.docx》由会员分享,可在线阅读,更多相关《网络课程设计任务书完整.docx(15页珍藏版)》请在冰豆网上搜索。
![网络课程设计任务书完整.docx](https://file1.bdocx.com/fileroot1/2023-4/16/362b5bd3-5954-4637-8cdb-c922d9304b52/362b5bd3-5954-4637-8cdb-c922d9304b521.gif)
网络课程设计任务书完整
计算机网络原理
课程设计说明书
发送TCP数据包
起止日期:
2010年06月28日至2010年07月02日
学生姓名
班级
学号
成绩
指导教师(签字)
计算机与通信学院
2010年7月02日
湖南工业大学
课程设计任务书
2009—2010学年第二学期
计算机与通信学院(系、部)通信工程专业071班级
课程名称:
计算机网络原理
设计题目:
发送TCP数据包
完成期限:
自2010年6月28日至2010年7月02日共1周
内
容
及
任
务
主要内容:
1.本程序的功能是填充一个TCP数据包,并发送给目的主机。
2.以命令行形式运行:
SendTCPsource_ipsource_portdest_ipdest_port
其中SendTCP为程序名;source_ip为源IP地址;source_port为源端口;dest_ip为目的IP地址;dest_port为目的端口。
3.其他的TCP头部参数自行设定。
4.数据字段为“Thisismyhomeworkofnetwork!
”.
5.成功发送后在屏幕上输出“sendOK”。
进
度
安
排
起止日期
工作内容
2010.6.28
分组、任务分配、课题理解
2010.6.29
查阅资料、算法分析设计、完成流程图的设计
2010.6.30
了解初始化原始套接字
2010.7.1
了解并且熟悉发送TCP数据包的过程
2010.7.2
程序调试、演示和答辩、修改设计说明书、个人总结
主
要
参
考
资
料
[1]谢希仁.计算机网络(第五版).电子工业出版社.2008
[2]吴功宜.计算机网络(第二版).清华大学出版社.2008
[3]吴功宜.计算机网络课程设计.机械工业出版社.2005(校图书馆:
TP393.466)
[4]吴英.计算机网络软件编程指导书.清华大学出版社.2008
[5]徐明伟.计算机网络原理实验教程.机械工业出版社.2008
指导教师(签字):
年月日
系(教研室)主任(签字):
年月日
课题名称
计算机网络原理
人数
3
组长
同组人员
课
题
的
主
要
内
容
和
要
求
主要内容:
1.本程序的功能是填充一个TCP数据包,并发送给目的主机。
2.以命令行形式运行:
SendTCPsource_ipsource_portdest_ipdest_port
其中SendTCP为程序名;source_ip为源IP地址;source_port为源端口;dest_ip为目的IP地址;dest_port为目的端口。
3.其他的TCP头部参数自行设定。
4.数据字段为“Thisismyhomeworkofnetwork!
”.
5.成功发送后在屏幕上输出“sendOK”。
主要要求:
1.算法正确,程序运行正常、输出清晰。
2.遵循良好的编程规范,程序要有合适的注释。
3.编程所使用的操作系统、语言、开发环境不限,但要在设计说明书中注明。
4.设计说明书逻辑清晰,主要算法用流程图表述,书写规范。
具体任务
1.初始化原始套接字
2.发送TCP数据包
时间安排与完成情况
6月28号,查找好相关资料、理解原理、并分配好任务
6月29号,熟悉了解初始化原始套接字的过程
6月30号,熟悉并且了解发送数据包的过程
7月01号,把两者结合起来,实现程序的功能
7月02号,编写调试,并且撰写课程设计报告
一、设计目的:
设计一个发送TCP数据包的程序,并根据本设计说明TCP数据包的结构以及TCP协议与IP协议的关系,使大家对TCP协议的工作原理有更深入的认识。
二、设计要求:
本程序的功能是填充一个TCP数据包,并发送给目的主机。
•以命令行形式运行:
SendTCPsource_ipsource_portdest_ipdest_port。
其中SendTCP为程序名;source_ip为源IP地址;source_port为源端口;dest_ip为目的IP地址;dest_port为目的端口。
•其他的TCP头部参数自行设定。
•数据字段为“Thisismyhomeworkofnetwork!
”.
•成功发送后在屏幕上输出“sendOK!
”。
三、设计分析:
•使用原始套接字
•定义IP头部、TCP头部和伪头部的数据结构
•填充数据包
•发送数据包
四、设计思想:
本课程设计的目标是发送一个TCP数据包,可以利用原始套接字来完成这个工作。
整个程序由初始化原始套接字和发送TCP数据包两个部分组成。
创建一个原始套接字,并设置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头。
注意,如果设置IP_HDRINCL选项,那么必须具有administrator权限,要不就必须修改注册表:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Afd\Parameter\
修改键:
DisableRawSecurity(类型为DWORD),把值修改为1。
如果没有,就添加。
BOOLFlag=TRUE;
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。
构造IP头和TCP头
这里,IP头和TCP头以及TCP伪部的构造请参考下面它们的数据结构。
计算校验和的子函数
在填充数据包的过程中,需要调用计算校验和的函数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);
}
五、程序流程图:
六、源程序代码:
#include
#include
#include
#include
#include
#include
#include
#include
#pragmacomment(lib,"ws2_32.lib")
#defineIPVER4//IP协议预定
#defineMAX_BUFF_LEN65500//发送缓冲区最大值
typedefstructip_hdr//定义IP首部
{
UCHARh_verlen;//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;
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(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;
}
//填充IP首部
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;//16位标识
ipHeader.frag_and_flags=0;//3位标志位
ipHeader.ttl=128;//8位生存时间
ipHeader.proto=IPPROTO_UDP;//协议类型
ipHeader.checksum=0;//检验和暂时为0
ipHeader.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.destIP;
psdHeader.mbz=0;
psdHeader.ptcl=ipHeader.proto;
psdHeader.tcpl=htons(sizeof(TCP_HEADER)+sizeof(tcp_send_data));
//填充TCP首部
tcpHeader.th_dport=htons(atoi(argv[4]));//16位目的端口号
tcpHeader.th_sport=htons(atoi(argv[2]));//16位源端口号
tcpHeader.th_seq=0;//SYN序列号
tcpHeader.th_ack=0;//ACK序列号置为0
//TCP长度和保留位
tcpHeader.th_lenres=(sizeof(tcpHeader)/sizeof(unsignedlong)<<4|0);
tcpHeader.th_flag=2;//修改这里来实现不同的标志位探测,2是SYN,1是//FIN,16是ACK探测等等
tcpHeader.th_win=htons((unsignedshort)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));
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;
}
七、实验运行结果:
所以进入dos,并进入到该可执行文件的目录下后在命令提示行下输入:
sendtcp192.168.18.312192.168.18.725,回车运行,运行截图如下:
本课程设计小结:
在对TCP数据包头部进行填充时,首先需要我们去充分了解它的数据结构,在这个过程中可以了解相应字节上应该存放的内容和它们的功能。
由于本次的课程设计只要求填充一个TCP数据包,然后将其发送出去,使用的数据发送函数是sendto(),成功地完成sendto()调用只能保证数据已经从本地发送出去,并不意味着数据传送到达目的地。
四、心得体会
经过此次计算机网络原理课程设计我学到了很多知识和学习方法,更加深了我对计算机网络原理课程的理解。
在此次的计算机网络课程设计中,我们一共做了三个程序设计的实验,帧封装、IP数据包解析和发送TCP数据包。
由于时间局限,最后我只选择了TCP数据包的发送作为课程设计答辩。
在开始编写程序的时候,我们束手无策,后来在参考了别人的程序之后,我开始有了一点头绪,于是开始动手编写程序了,幸好我之前C++学得不错,在编写完部分程序以后,经调试慢慢的修改了一些错误,但是最终使得程序还是能够运行!
此次课程设计,对我来说不仅是一种量的升级,更是一种质的升级。
虽然在此次过程中我还是遇到了不少的问题,但是最后在组长和老师的帮助下,我终于完成了在这次课程设计中的任务。
此次课程设计,在编写程序的过程中,我用到了很多的函数,这些函数的运用使得程序简便而且正确的运行出来。
为了正确的实现这些函数,我们查阅了很多相关的资料,从中获得了大量的有用的信息,收获也颇丰富。
总的来说,这次设计让我受益匪浅。
此次课程设计不仅增强了我的思维能力,也增强了我的动手能力,为我以后的学习和工作奠定了良好的基础。