什么是UDP协议
UDP协议的全称是用户数据报在网络中它与TCP协议一样用于处理数据包在OSI模型中在第四层——传输层处于IP协议的上一层UDP有不提供数据报分组组装和不能对数据包的排序的缺点也就是说当报文发送之后是无法得知其是否安全完整到达的
为什么要使用UDP
在选择使用协议的时候选择UDP必须要谨慎在网络质量令人不十分满意的环境下UDP协议数据包丢失会比较严重但是由于UDP的特性它不属于连接型协议因而具有资源消耗小处理速度快的优点所以通常音频视频和普通数据在传送时使用UDP较多因为它们即使偶尔丢失一两个数据包也不会对接收结果产生太大影响比如我们聊天用的ICQ和OICQ就是使用的UDP协议
在Java中操纵UDP
使用位于JDK中包下的DatagramSocket和DatagramPacket类可以非常方便地控制用户数据报文
在描述它们之前必须了解位于同一个位置的InetAddress类InetAddress实现了Javaio Serializable接口不允许继承它用于描述和包装一个Internet IP地址通过三个方法返回InetAddress实例
getLocalhost()返回封装本地地址的实例
getAllByName(String host)返回封装Host地址的InetAddress实例数组
getByName(String host)返回一个封装Host地址的实例其中Host可以是域名或者是一个合法的IP地址
DatagramSocket类用于创建接收和发送UDP的Socket实例和Socket类依赖SocketImpl类一样DatagramSocket类的实现也依靠专门为它设计的DatagramScoketImplFactory类DatagramSocket类有个构建器
DatagramSocket()创建实例这是个比较特殊的用法通常用于客户端编程它并没有特定监听的端口仅仅使用一个临时的
DatagramSocket(int port)创建实例并固定监听Port端口的报文
DatagramSocket(int port InetAddress localAddr)这是个非常有用的构建器当一台机器拥有多于一个IP地址的时候由它创建的实例仅仅接收来自LocalAddr的报文
值得注意的是在创建DatagramSocket类实例时如果端口已经被使用会产生一个SocketException的异常抛出并导致程序非法终止这个异常应该注意捕获DatagramSocket类最主要的方法有个
Receive(DatagramPacket d)接收数据报文到d中receive方法产生一个阻塞
Send(DatagramPacket d)发送报文d到目的地
SetSoTimeout(int timeout)设置超时时间单位为毫秒
Close()关闭DatagramSocket在应用程序退出的时候通常会主动释放资源关闭Socket但是由于异常地退出可能造成资源无法回收所以应该在程序完成时主动使用此方法关闭Socket或在捕获到异常抛出后关闭Socket
阻塞是一个专业名词它会产生一个内部循环使程序暂停在这个地方直到一个条件触发
DatagramPacket类用于处理报文它将Byte数组目标地址目标端口等数据包装成报文或者将报文拆卸成Byte数组应用程序在产生数据包是应该注意TCP/IP规定数据报文大小最多包含个通常主机接收个字节但大多数平台能够支持字节大小的报文DatagramPacket类的构建器共有个
DatagramPacket(byte[] buf int length InetAddress addr int port)从Buf数组中取出Length长的数据创建数据包对象目标是Addr地址Port端口
DatagramPacket(byte[] buf int offset int length InetAddress address int port)从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[];
DatagramSocket ds = new DatagramSocket();
//开始监视端口
DatagramPacket ip = new DatagramPacket(buf buflength);
//创建接收数据报的实例
while (true)
{
dsreceive(ip);
//阻塞直到收到数据报后将数据装入IP中
Systemoutprintln(new String(buf));
}
{发送数据的客户端}
InetAddress target = InetAddressgetByName();
//得到目标机器的地址实例
DatagramSocket ds = new DatagramSocket();
//从端口发送数据报
String hello = Hello I am come in!;
//要发送的数据
byte[] buf = hellogetBytes();
//将数据转换成Byte类型
op = new DatagramPacket(buf buflength target );
//将BUF缓沖区中的数据打包
dssend(op);
//发送数据
dsclose();
//关闭连接