赞
踩
TCP/IP协议族是构建互联网的基石协议。在互联网中,从一台计算机向另外一台计算机传送数据,数据包可以通过两种协议传输。其中一种就是传输控制协议(Transmission Control Protocol,TCP)。TCP能够确保数据的传送,也确保数据包以它们正确的顺序传送,是一种提供可靠连接的传送协议。由于Java语言支持基于流的通信,即是用TCP协议进行传输,所以本次的课程设计将基于Java语言,设计出一个可以发送TCP数据包的程序。
传输控制协议(TCP),Java,套接字(Socket),IP,端口(Port)
在互联网的四层协议中,TCP位于IP层之上,应用层之下的传输层。不同主机的应用层之间经常需要可靠的、像管道一样的连接。而面向连接、提供可靠传输的TCP协议则正好能够满足这一需求。因此被广泛利用。
掌握TCP数据包的发包原理和功能的实现,有利于我们能够更进一步地学习和利用更多应用层上的应用和技术,如文件传送(FTP)、远程登录(RemoteLogin)等。
本次课程设计要求我们能够实现以下效果:
(1) 以命令行形式运行:
SendTCP source_IP source_port dest_ip dest_port
其中,SendTCP为程序名,source_IP为源端IP地址,source_port为源端口,dest_ip 为目的IP地址,dest_port为目的端口
(2) 其他的TCP头部参数请自行设定。
(3) 数据字段为“Thisis my homework of network ,I am happy!”.
(4) 成功发送后在屏幕上输出“SendOK”。
在本次课程设计中,要求发送一段数据包,里面包含一段数据信息。同时,为了验证数据包发送成功,还需要进行验证。因此需要实现至少发送数据包和验证发送是否成功的两项功能。建立服务端发送数据段,客户端接收数据段并发送反馈信息。当它们分别运行在不同的主机上,运行程序。根据程序的运行情况,便能验证这两项功能。
在服务端,我们首先建立对源端口的监听。当客户端成功连接到源端口时,服务端即按要求发送数据段“This is my homework of network ,I amhappy!”到目的IP、端口。客户端,新建端口的监听,当收到数据段后发送“SendOK!”反馈给服务端。通过这样的数据包传送的数据,便能实现以上两种功能,见图3。要注意的是,服务端的源IP、端口即为客户端的目的IP、端口;服务端的目的IP、端口即为客户端的源IP、端口。
本次的课程设计在Java语言的平台上利用Java语言实现。为了实现在两台计算机发送数据包的功能。本次实验采用了物理机和虚拟机模拟在同一个局域网中。其中物理机采用Windows 8.1系统,IP地址为192.168.126.53,而虚拟机则采用Windows XP系统,IP地址为192.168.126.52。如图4所示。
本次实验采用了String类型保存字符,而端口号则采用Int类型。而由于文本I/O需要编码和解码,所以,二进制I/O的效率比文本I/O的效率更高。因此最好使用二进制I/O在服务端和客户端之间进行数据传输,以便提高效率。因此,在读入和写入分别采用了DataInputStream和DataOutStrea这两个类。
不论是客户端还是服务端,根据要求,都需要读入IP和端口信息。而服务端的源IP、端口即为客户端的目的IP、端口;服务端的目的IP、端口即为客户端的源IP、端口。
- String sourceIP = args[0];//源IP
- int sourcePort = Integer.parseInt(args[1]);//源端口
- String destinationIP = args[2];//目的IP
- int destinationPort = Integer.parseInt(args[3]);//目的端口
无论是服务端还是客户端都需要建立套接字(Socket)。建立套接字有两种方法,一种是主动发送信息的。例外一种则是被动接收信息再发出反馈(监听)。在本次课程实验中,无论是两端既需用到主动发信息又需要用到监听。
- //主动发送信息,发送方向为目的IP的目的端口
- Socket socket = new Socket(destinationIP, destinationPort);
- DataOutputStream dataOutputStream
- = new DataOutputStream(socket.getOutputStream());
- dataOutputStream.writeUTF("Response Please!");
- //监听,接收发给源IP的源端口信息。
- ServerSocket serverSocket = new ServerSocket(sourcePort);
- socket = serverSocket.accept();
作为本次课程实验的重点,发送和接收是否成功是本次课程设计是否成功的关键。为了保证程序能够成功运行,本次发送的数据均采用二进制数据流。
- //发送信息
- DataOutputStream dataOutputStream
- = new DataOutputStream(socket.getOutputStream());
- dataOutputStream.writeUTF("Response Please!");
- //接收信息
- DataInputStream dataInputStream
- = new DataInputStream(socket.getInputStream());
- String dataSegment=dataInputStream.readUTF();
服务端在本次课程设计中,主要负责往目的套接字(目的IP+端口)发送数据段“Thisis my homework of network ,I am happy! ”,并接收来时目的套接字返回的数据段“SendOK!”,见图6。
- //记录源和目的套接字的信息
- String sourceIP = args[0];
- int sourcePort = Integer.parseInt(args[1]);
- String destinationIP = args[2];
- int destinationPort = Integer.parseInt(args[3]);
-
- //建立监听
- ServerSocket serverSocket = new ServerSocket(sourcePort);
- Socket socket = serverSocket.accept();
-
- //接收来自客户端的信息
- DataInputStream dataInputStream
- = new DataInputStream(socket.getInputStream());
- //发送信息
- String dataSegment = "This is my homework of network ,I am happy!";
- DataOutputStream dataOutputStream
- = new DataOutputStream(socket.getOutputStream());
- dataOutputStream.writeUTF(dataSegment);
-
- //接收成功信息
- socket = new Socket(destinationIP, destinationPort);
- dataOutputStream = new DataOutputStream(socket.getOutputStream());
- dataOutputStream.writeUTF("Successfully Received!");
-
- dataInputStream = new DataInputStream(socket.getInputStream());
- dataSegment=dataInputStream.readUTF();
- PrintMessage("接收到来自" + socket.getInetAddress().toString().substring(1) + ","
- + socket.getPort() + "号端口的信息");
- PrintMessage("信息内容为:" + dataSegment);
-
- //关闭流
- dataInputStream.close();
- dataOutputStream.close();
- socket.close();
- serverSocket.close();
客户端在本次课程设计中,主要负责的是接收来自服务端的信息,并发出反馈信息“Send OK!”,见图7。
- //尝试连接
- Socket socket = new Socket(destinationIP, destinationPort);
- DataOutputStream dataOutputStream
- = new DataOutputStream(socket.getOutputStream());
- dataOutputStream.writeUTF("Response Please!");
-
- //获得回应
- DataInputStream dataInputStream
- = new DataInputStream(socket.getInputStream());
- String dataSegment = dataInputStream.readUTF();
- PrintMessage("接收到来自" + socket.getInetAddress().toString().substring(1) + ","
- + socket.getPort() + "号端口的信息");
- PrintMessage("信息内容为:" + dataSegment);
-
- //回复
- ServerSocket serverSocket = new ServerSocket(sourcePort);
- socket = serverSocket.accept();
- dataOutputStream = new DataOutputStream(socket.getOutputStream());
- dataOutputStream.writeUTF("Send OK!");
(1) 命令行界面不够美观且操作性不够强
(2) 每次都输入4个参数太麻烦了
(1) 改用图形界面,并美化界面。但可能速度上不够现在的快。
(2) 仿照命令提示符(cmd),可以缺省输入。
[1]Y.Daniel Liang.Java语言程序设计(基础篇)[M].李娜,译.北京:机械工业出版社,2011:527-535
[2]Y.Daniel Liang.Java语言程序设计(进阶篇)[M].李娜,译.北京:机械工业出版社,2011:258-264
[3]谢希仁.计算机网络简明教程(第二版)[M].北京:电子工业出版社,2013:123-143
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。