一、DatagramPacket类: 如果把DatagramSocket比作创建的港口码头,那么DatagramPacket就是发送和接收数据的集装箱。 构造函数:一个用来接收数据,一个用来发送数据 publicDatagramPacket(byte[] buf,int length) //接收数据 构造DatagramPacket用来接收长度为 length的包。 publicDatagramPacket(byte[] buf,int length,InetAddress address,intport) 构造数据报文包用来把长度为length的包传送到指定宿主的指定的端口号。 getAddress() 返回接收或发送此数据报文的机器的IP地址。 getData() 返回接收的数据或发送出的数据。 getLength() 返回发送出的或接收到的数据的长度。 getPort() 返回接收或发送该数据报文的远程主机端口号。 二、DatagramSocket类 此类表示用来发送和接收数据报包的套接字。数据报套接字是包投递服务的发送或接收点。 DatagramSocket(intport) 创建数据报套接字并将其绑定到本地主机上的指定端口。 DatagramSocket(intport, InetAddress laddr) 创建数据报套接字,将其绑定到指定的本地地址。 receive(DatagramPacketp) 从此套接字接收数据报包。 voidsend(DatagramPacket p) 从此套接字发送数据报包。 bind(SocketAddressaddr) 将此 DatagramSocket绑定到特定的地址和端口。 voidclose() 关闭此数据报套接字。 voidconnect(InetAddress address, int port) 将套接字连接到此套接字的远程地址。 voidconnect(SocketAddress addr) 将此套接字连接到远程套接字地址(IP地址 +端口号)。 voiddisconnect() 断开套接字的连接。 getInetAddress() 返回此套接字连接的地址。 InetAddressgetLocalAddress() 获取套接字绑定的本地地址。 三、InetAddress类 InetAddress用于表示计算机IP地址的一个类,而在日常应用中的IP地址用"192.168.0.1", "WWW.it315.org"等字符串格式表示的。 getByName方法 getHostAddress方法 四、UDP通信示例代码: 发送端代码UdpSend.java: import java.net.*; publicclass UdpSend {
public static void main(String[] args) throwsException{
DatagramSocket ds=new DatagramSocket(); String strInfo="Hello Taohx"; ds.send(newDatagramPacket(strInfo.getBytes(),strInfo.length(), InetAddress.getByName("59.64.157.93"),3000)); ds.close(); } } 接收代码UdpRecv.java: importjava.net.*; public class UdpRecv {
public static void main(String[] args) throwsException{
DatagramSocket ds=new DatagramSocket(3000); byte [] buf=new byte[1024]; DatagramPacket dp=new DatagramPacket(buf,1024); ds.receive(dp); String strInfo= newString(dp.getData(),0,dp.getLength())+ " from"+dp.getAddress().getHostAddress()+":"+dp.getPort(); System.out.println(strInfo); ds.close(); } } 注意:若发送中文信息时,因为中文字符占两个字节,故发送代码ds.send要修改如下才可正确地发送中文信息, ds.send(newDatagramPacket(strInfo.getBytes(),strInfo.getBytes().length, InetAddress.getByName("59.64.157.93"),3000)); *********************************************************************************************************** 在Java中操纵UDP 使用位于JDK中Java.net包下的DatagramSocket和DatagramPacket类,可以非常方便地控制用户数据报文。 在描述它们之前,必须了解位于同一个位置的InetAddress类。InetAddress实现了Java.io.Serializable接口,不允许继承。它用于描述和包装一个InternetIP地址,通过三个方法返回InetAddress实例: getLocalhost():返回封装本地地址的实例。 getAllByName(Stringhost):返回封装Host地址的InetAddress实例数组。 getByName(Stringhost):返回一个封装Host地址的实例。其中,Host可以是域名或者是一个合法的IP地址。 DatagramSocket类用于创建接收和发送UDP的Socket实例。和Socket类依赖SocketImpl类一样,DatagramSocket类的实现也依靠专门为它设计的DatagramScoketImplFactory类。DatagramSocket类有3个构建器: DatagramSocket():创建实例。这是个比较特殊的用法,通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。 DatagramSocket(intport):创建实例,并固定监听Port端口的报文。 DatagramSocket(intport, InetAddresslocalAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文。 值得注意的是,在创建DatagramSocket类实例时,如果端口已经被使用,会产生一个SocketException的异常抛出,并导致程序非法终止,这个异常应该注意捕获。DatagramSocket类最主要的方法有4个: Receive(DatagramPacketd):接收数据报文到d中。receive方法产生一个“阻塞”。 Send(DatagramPacketd):发送报文d到目的地。 SetSoTimeout(inttimeout):设置超时时间,单位为毫秒。 Close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Socket。 “阻塞”是一个专业名词,它会产生一个内部循环,使程序暂停在这个地方,直到一个条件触发。 DatagramPacket类用于处理报文,它将Byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成Byte数组。应用程序在产生数据包是应该注意,TCP/IP规定数据报文大小最多包含65507个,通常主机接收548个字节,但大多数平台能够支持8192字节大小的报文。DatagramPacket类的构建器共有4个: DatagramPacket(byte[]buf, int length, InetAddress addr, intport):从Buf数组中,取出Length长的数据创建数据包对象,目标是Addr地址,Port端口。 DatagramPacket(byte[]buf, int offset, int length, InetAddress address, intport):从Buf数组中,取出Offset开始的、Length长的数据创建数据包对象,目标是Addr地址,Port端口。 DatagramPacket(byte[]buf, int offset, int length):将数据包中从Offset开始、Length长的数据装进Buf数组。 DatagramPacket(byte[]buf, int length):将数据包中Length长的数据装进Buf数组。 DatagramPacket类最重要的方法就是getData()了,它从实例中取得报文的Byte数组编码。 简单的实例说明 {
接收数据的服务器} byte[] buf = new byte[1000]; DatagramSocket ds= new DatagramSocket(12345); //开始监视12345端口 DatagramPacketip = new DatagramPacket(buf, buf.length); //创建接收数据报的实例 while(true) {
ds.receive(ip); //阻塞,直到收到数据报后将数据装入IP中 System.out.println(newString(buf)); } {
发送数据的客户端} InetAddress target =InetAddress.getByName(“www.xxx.com“); //得到目标机器的地址实例 DatagramSocketds = new DatagramSocket(9999); //从9999端口发送数据报 Stringhello = “Hello, I am come in!”; //要发送的数据 byte[]buf = hello.getBytes(); //将数据转换成Byte类型 op= new DatagramPacket(buf, buf.length, target,12345); // |