网络课程设计 发送TCP数据包.docx
《网络课程设计 发送TCP数据包.docx》由会员分享,可在线阅读,更多相关《网络课程设计 发送TCP数据包.docx(13页珍藏版)》请在冰豆网上搜索。
网络课程设计发送TCP数据包
成绩评定表
学生姓名
班级学号
专业
课程设计题目
发送TCP数据包
评
语
组长签字:
成绩
日期
2012年月日
课程设计任务书
学院
专业
学生姓名
班级学号
课程设计题目
发送TCP数据包
实践教学要求与任务:
发送TCP数据包的具体步骤:
(1)以命令行形式运行:
SendTCP和ListenTCP,其中,SendTCP是发送程序,ListenTCP是监听程序,发送端套接字为127.0.0.120000,接收端套接字为127.0.0.110000。
(2)数据字段为“ILoveChina!
”。
(3)成功发送后在屏幕上输出“SendOK!
”。
任务交付:
1.程序源代码;2课程设计论文及电子文档。
进度安排:
本课程设计时间为17、19教学周。
其中包含设计、代码调试、课程设计论文撰写几个阶段。
第1周查找资料、完成初步设计、代码设计与初步调试;
第2周调试、测试、验收、课程设计论文撰写、答辩。
指导教师:
年月日
专业负责人:
年月日
学院教学副院长:
年月日
目录
1概述4
1.1设计目的4
1.2设计要求4
1.3设计原理4
2详细设计7
2.1程序流程图7
2.2计算校验和8
3程序代码及运行结果9
3.1程序清单9
3.2运行结果11
4总结14
5参考文献15
1概述
1.1设计目的
TCP(传输控制协议)是一种面向连接的、可靠的传输层协议。
TCP协议在网络层IP协议的基础上,向应用层用户进程提供可靠的、全双工的数据流传输。
本课程设计的目的就是设计一个发送TCP数据包的程序,并根据本设计说明TCP数据包的结构以及TCP协议与TP协议的关系。
1.2设计要求
本设计的功能是填充一个TCP数据包,并发送给目的主机。
程序具体要求如下:
(1)以命令行形式运行:
SendTCP和ListenTCP,其中,SendTCP是发送程序,ListenTCP是监听程序,发送端套接字为127.0.0.120000,接收端套接字为127.0.0.110000。
(2)数据字段为“ILoveChina!
”。
(3)成功发送后在屏幕上输出“SendOK!
”。
1.3设计原理
互联网络层是TCP/IP协议参考模型中的关键部分。
当多信息的传输要求比较高时,我们才用TCP来实现数据的传输。
本程序是在windows环境下实现了发送TCP数据包的功能。
主要包括定义IP头部、TCP头部、和伪头部的数据结构,填充IP头部,计算IP头部校验和,构造TCP伪头部,填充TCP头部,计算TCP头部校验和,发送TCP数据报。
接着是对客户端程序的开发,程序结构与服务端程序类似,也包括定义IP头部、TCP头部、和伪头部的数据结构。
当应用进程需要通过TCP发送时,它就将此应用层报文传送给执行TCP协议的传输实体。
TCP传输实体将用户数据加上TCP报头,形成TCP数据包,在TCP数据包上增加IP头部,形成IP包。
TCP协议的数据传输单位称为报文段,报文段报头的长度是20B-60B,选项部分长度最多为40B。
TCP报文段主要包括:
(1)端口号:
端口号字段包括源端口号和目的端口号。
每个端口号的长度是16位,分别表示发送该TCP包的应用进程的端口号和接收该TCP数据包的应用进程端口号。
(2)序号:
长度为32位。
由于TCP协议是面向数据流的,它所传送的报文段可以视为连续的数据流,因此需要给每一个字节编号。
序号字段的“序号”指的是本报文段数据的第一个字节的序号。
(3)报文长度:
该字段长度为4位。
TCP报文长度是以4B为一个单元来计算的,实际上报文长度在20B-60B之间,因此这个字段的值在5-15之间。
(4)TCP头部数据:
包括源端口号、序号、确认号、报文长度、保留URG、ACK、PSH,数据包头部的格式RST、SYN目的端口号。
(5)FIN:
紧急指针,保留长度16位,留作以后使用,目前全部置0。
保留控制:
这个字段定义了6种不同的标识,每一个标志占一位或多位。
URG位为1时,表明应尽快把数据传送给应用程序,否则表明允许数据在缓存中存放一段时间。
RST位为1时,表明要强制切断连接。
SYN位1时,表明有确立连接的请求,这时,把序号字段的初始值作为序号字段的值,以便开始通信。
FIN位为1时,表明发送方已经没有数据发送了,长度为16位,指向必须紧急处理的位置,只有当标志URG=1时紧急指针才生效。
从TCP报头后面的报文数据开始,到紧急指针所指出长度的数据,就是必须紧急处理的数据。
下面分别给出IP头部、TCP头部、和伪头部的数据结构图示:
(1)TCP数据包和IP的关系如图1-1所示:
图1-1TCP数据包和IP的关系
(2)TCP协议的传输单元称为报文段、其格式如1-2所示:
图1-2TCP协议报文段格式
(3)伪头部的格式如图1-3所示:
08162431
源IP地址
目的IP地址
00000000
协议号(6)
TCP长度
图1-3伪头部数据格式
2详细设计
2.1程序流程图
本程序采用的是顺序结构,其流程图如图2-1所示:
图2—1程序流程图
2.2计算校验和
为了计算一份数据报的IP检验和,首先把检验和字段置为0。
然后,对首部中每个16bit进行二进制反码求和(整个首部看成是由一串16bit的字组成),结果存在检验和字段中。
当收到一份IP数据报后,同样对首部中每个16bit进行二进制反码的求和。
由于接收方在计算过程中包含了发送方存在首部中的检验和,因此,如果首部在传输过程中没有发生任何差错,那么接收方计算的结果应该为全1。
如果结果不是全1(即检验和错误),那么IP就丢弃收到的数据报。
但是不生成差错报文,由上层去发现丢失的数据报并进行重传。
校验和(checksum),在数据处理和数据通信领域中,用于校验目的的一组数据项的和。
这些数据项可以是数字或在计算检验的过程中看作数字的其它字符串。
本程序中,“in_cksum”为计算校验和的函数,在填充数据包的过程中,需要调用这个函数两次,分别用于校验IP头部和TCP头部(加上伪头部)。
3程序代码及运行结果
3.1程序清单
监听TCP数据包的服务端程序:
import.*;
importjava.io.*;
publicclassListenTCP//监听TCP数据包的服务端程序
{
publicstaticvoidmain(String[]args)
{
ServerSocketlisten=null;//定义一个ServerScoket类型的引用
Socketsoc=null;//定义Socket的应用,用于套接字连接
Stringmessage=null;
BufferedReaderbf=null;//定义一个BufferedReader类型的读内容的引用
InputStreamReaderisr=null;//定义一个可读输入流
try{
listen=newServerSocket(10000);//创建一个监听1000端口的对象
soc=listen.accept();//当有socket连接所监听的端口时,连接上该socket
System.out.println("*******************************************");
System.out.println("serverok");
System.out.println("*******************************************");
System.out.println("");
isr=newInputStreamReader(soc.getInputStream());//创建一个来自套接字soc
的可读输入流
bf=newBufferedReader(isr);//把soc的可读输入流作为参数创建一个
BufferedReader
message=bf.readLine();//以每行为单位读取从客户端发来的数据
System.out.println("Socket:
"+soc);//显示出发送方的IP地址和端口号
System.out.println("Receivethemessagefrom:
"+message);//显示接收到的数
据
System.out.println("");
System.out.println("*******************************************");
isr.close();//关闭输入流isr
bf.close();//关闭字符流bf
soc.close();//关闭Socket套接字
}
catch(Exceptione)//异常处理
{
System.out.println("Error:
"+e);
}
}
}
发送TCP数据包的发送端程序:
import.*;
importjava.io.*;
publicclassSendTCP
{
publicstaticvoidmain(String[]args)throwsIOException
{
if(args.length!
=4)
{
System.out.println("您在命令行的输入格式有误,请按照以下格式重新输入!
");
System.out.println("源IP地址源端口目的IP地址目的端口");
System.exit(0);
}
Stringsource_ip=args[0];
intsource_port=Integer.parseInt(args[1]);
Stringdest_ip=args[2];
intdest_port=Integer.parseInt(args[3]);
if(dest_port!
=10000)
{
System.out.println("请保持目的端口为10000!
");
System.exit(0);
}
OutputStreamos=null;
PrintStreamps=null;
BufferedReaderbf=null;
Stringmessage="Thisismyhomeworkofnetwork!
";
Socketsoc=null;
try{
soc=newSocket(dest_ip,dest_port);
System.out.println("***************************************************");
System.out.println("Connecttoserver......");
System.out.println("***************************************************");
System.out.println();
bf=newBufferedReader(
newInputStreamReader(System.in));
System.out.print("Pleaseinputthemessage:
");
message=bf.readLine();
os=soc.getOutputStream();
ps=newPrintStream(os);
ps.println(message);
bf.close();
ps.close();
os.close();
System.out.println();
System.out.println("***************************************************");
System.out.println("SendOK!
");
System.out.println("Themessagewassendtotheaddress:
"+dest_ip+"["+dest_port+"]");
System.out.println("***************************************************");
soc.close();
}catch(Exceptione)
{
System.out.println(e);
}
}
}
3.2运行结果
(1)发送端套接字和接收端套接字设定:
设定套接字格式必须正确,否则程序将出现异常,这里我们是发送给本机,所以选取系统默认的本地IP,可以设定成发送套接字为127.0.0.120000,接收套接字为127.0.0.110000,设定成功之后,系统会显示正在进行连接——Connecttoserver如图3-1所示:
图3-1套接字的设定
(2)“握手”成功:
系统自动提示连接成功,可以进行数据传送,如图3-2所示:
图3-2连接(“握手”)成功
(3)信息发送:
发送的信息为“ILoveChina!
”,信息发送成功之后,系统提示“SendOK!
”
运行结果如图3-3所示:
图3-3发送数据成功
(4)信息接收:
系统显示接收到的信息“ILoveChina!
”,结果如图3-4所示:
图3-4数据接收成功
4总结
经过本次课设,我知道了如何在电脑中实现IP的格式检测。
不仅要判断取值范围,还要判断标点符号、是否具有32位等等。
并且我也学习到了两个新函数的运用,一个是将字符型转化成int形的函数atoi(),另一个是字符串分片函数strtok()。
另外,对IP地址与子网掩码的关系也有了进一步的了解。
我认为,用mask的值控制比较子网与主网的子网号是否一致,是一个比较精彩的地方。
在书上学来的东西应用到实际中还是有一定困难,开始做程序时,IP地址格式判断的条件我没有考虑全,所以刚开始总出错,这个问题以后也会注意。
我相信本次课程设计能给我在今后的学习生活中给以帮助。
5参考文献
[1]《计算机网络(第5版)》 谢希仁著电子工业出版社2009
[2]《计算机网络》宋凯刘念主编清华大学出版社2010
[3]《数据通信与网络(第四版)》吴时霖周正康吴永辉译电子工业出版社2010
[4]《C程序设计(第四版)》谭浩强著清华大学出版社2009
[5]《TCP/IP协议族(第三版)》福罗赞著清华大学出版社2010