System.out.println(data[i]);}
sps=newSudpSocket("localhost",12345,data);
}catch(IOExceptione1)
{e1.printStackTrace();sps=null;}
try{
sps.dgs.send(sps.dgp);
}catch(IOExceptione)
{e.printStackTrace();sps=null;}
System.out.println("overthesending");}}
4.NetFileW类
packageudp;
importjava.io.File;
importjava.io.FileOutputStream;
importjava.io.IOException;
publicclassNetFileW{
publicNetFileW(StringfilePath)
{this.filePath=filePath;
}
privateStringfilePath;
publicvoidwrite(byte[]data)throwsIOException{
//通过将给定路径名字符串转换成抽象路径名来创建一个新File实例
Filefile=newFile(filePath);
FileOutputStreamout=newFileOutputStream(file);//创建一个FileOutputStream流
out.write(data);
}
publicStringgetFilePath(){
returnfilePath;
}
publicvoidsetFilePath(StringfilePath)
{this.filePath=filePath;
}}
执行结果:
首先,本代码中要发送的文件目录及文件名为D:
/JAVA/MyEclipse6.0/UDP/happy.txt。
创建好相应文件之后,先运行CudpSocket类,然后再运行SudpSocket发送文件happy.txt。
结果如下:
SudpSocket下的控制台:
data.length:
1024
104
101
108
108
111
33
0
(…)
0
overthesending
CudpSocket下的控制台
entertheserver
data.length:
1000
104
101
108
108
111
33
0
(…)
0
2.请参考步骤1的代码及本章的DatagramTester.java、MulticastSender.java、MulticastReceiver.java程序,实现基于UDP的组播文件传输功能,即可以向组内用户群发文件的功能(要求:
文件大小大于1K的,设计使用多个UDP报文进行发送)。
1.MulticastSender类
import.*;
importjava.io.*;
publicclassMulticastSender{
publicstaticvoidmain(String[]args)throwsException{
InetAddressgroup=InetAddress.getByName("229.0.0.1");//缓存
intport=4000;//设置端口4000
MulticastSocketms=null;
try{
ms=newMulticastSocket(port);//创建多播套接字并将其绑定到特定端口
//ms.joinGroup(group);
while(true){
Stringmessage="Hello"+newjava.util.Date();
byte[]buffer=message.getBytes();
DatagramPacketdp=newDatagramPacket(buffer,buffer.length,group,port);
//构造数据报包,用来将长度为length的包发送到指定主机上的指定端口号
ms.send(dp);
System.out.println("发送数据报给"+group+":
"+port);
Thread.sleep(1000);
}
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(ms!
=null){
try{
ms.leaveGroup(group);
ms.close();
}
catch(IOExceptione){}
}
}
}
}
2.MulticastReceiver类
import.*;
importjava.io.*;
publicclassMulticastReceiver{
publicstaticvoidmain(String[]args)throwsException{
InetAddressgroup=InetAddress.getByName("229.0.0.1");//设置缓存
intport=4000;
MulticastSocketms=null;
try{
ms=newMulticastSocket(port);//创建多播套接字并将其绑定到特定端口
ms.joinGroup(group);
byte[]buffer=newbyte[8192];//构造一个新分配的Byte对象,以表示指定的byte值
while(true){
DatagramPacketdp=newDatagramPacket(buffer,buffer.length);
//构造数据报包,用来将长度为length的包发送到指定主机上的指定端口号
ms.receive(dp);
Strings=newString(dp.getData(),0,dp.getLength());
//构造一个新的String,方法是使用指定的字符集解码字节的指定子数组
System.out.println(s);
}
}catch(IOExceptione){
e.printStackTrace();
}finally{
if(ms!
=null){
try{
ms.leaveGroup(group);
ms.close();
}
catch(IOExceptione){}
}
}
}
}
MulticastSender发送的数据包给224.0.0.1:
4000
MulticastReceiver1和MulticastReceiver2分别收到两条信息
四思考题
试请给出UDP支持下的Client/Server通信的全过程。
可以用于管道程序通过UDP在不同机器之间的传送
1.Client类
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
import.DatagramPacket;
import.DatagramSocket;
import.InetAddress;
import.SocketException;
publicclassCollectPipe{
privatestaticfinalintDEFAULT_PORT=8888;
//shouldholdthemaxsizeofaudppacket
privatestaticfinalintBUFFER_LENGTH=2048;
publicstaticvoidmain(String[]args)throwsException{
if(args.length<1){
System.out.printf("Usage:
java%shost[port]\n",CollectPipe.class
.getCanonicalName());
System.exit(0);
}
intport=DEFAULT_PORT;
if(args.length>1)
port=Integer.parseInt(args[1]);
DatagramSocketaSocket=null;
try{
aSocket=newDatagramSocket();
InetAddressserverAddress=InetAddress.getByName(args[0]);
BufferedReaderin=newBufferedReader(newInputStreamReader(
System.in));
Stringstr="";
while(str!
=null){
str=in.readLine();
if(str==null)
break;
byte[]buffer=str.getBytes();
DatagramPacketpacket=newDatagramPacket(buffer,
buffer.length,serverAddress,port);
aSocket.send(packet);
}
}catch(SocketExceptione){
System.out.println("Socket:
"+e.getMessage());
}catch(IOExceptione){
System.out.println("IO:
"+e.getMessage());
}finally{
if(aSocket!
=null)
aSocket.close();
}
}
}
2.Server端
importjava.io.IOException;
import.DatagramPacket;
import.DatagramSocket;
import.SocketException;
publicclassCollectPipeServer{
privatestaticfinalintDEFAULT_PORT=8888;
privatestaticfinalintBUFFER_LENGTH=2048;
publicstaticvoidmain(Stringargs[]){
intport=DEFAULT_PORT;
if(args.length>0)
port=Integer.parseInt(args[0]);
byte[]buffer=newbyte[BUFFER_LENGTH];
DatagramSocketaSocket=null;
try{
aSocket=newDatagramSocket(port);
System.out.printf("CollectPipelisteningonport%d...\n",port);
while(true){
DatagramPacketrequest=newDatagramPacket(buffer,
buffer.length);
aSocket.receive(request);
Stringmessage=newString(buffer,0,request.getLength());
System.out.println(message);
}
}catch(SocketExceptione){
System.out.println("Socket:
"+e.getMessage());
}catch(IOExceptione){
System.out.println("IO:
"+e.getMessage());
}finally{
if(aSocket!
=null)
aSocket.close();
}
}
}
答:
UDP报文中包括目的主机IP和报文长度,当它被发送后,网络中的路由器根据目的IP一级一级的转发,最后到达目的主机。
五.实验总结和体会
通过这次试验,让我对数据报通信的原理以及利用Java语言实现C/S下的UDP通信有了更深的理解,期待下次的进步,加油~