这篇博文是本文学习《Java网络程序设计》书中第5章数据报套接字的学习总结。初学者网友学习这篇Java数据报套接字文章,如果难于理解文章前面理论部分,可以先运行后面的程序,边看运行后面的程序边理解前面的原理,这对初学者是最好的方法。所有源代码都在文章后面我的github链接代码中。
——惠州学院13网络工程 吴成兵 20160609
目录 1
一 数据报套接字概述
流套接字的每个连接均要花费一定的时间,为了减少这种开销,网络API提供了第二种套接字——数据报套接字(DatagramSocket),又称自寻址套接字。
数据报套接字基于的协议是UDP协议,采用的是一种尽力而为(Best-Effort)的传送数据的方式,它只是把数据的目的地记录在数据报包(DatagramPacket)中,然后就直接放在网络上,系统不保证数据是否能安全送到,或者什么时候可以送到,也就是说它并不保证传送的质量。UDP在每一个自寻址包中包含了错误检测信息,在每个自寻址包到达目的地之后UDP进行简单的错误检查,如果检查失败,UDP将抛弃这个自寻址包,也不会从发送者那里重新请求替代者。这与通过邮局发送信件相似,发信人在发信这前不需要与收信人建立连接,同样也不能保证信件能到达发信人那里。
可见,UDP的优点是效率高,并且比较灵活,一般用于质量和实时性要求不是很高的情况,比如实时音频和视频应用中。
DatagramSocket本身只是码头,不维护状态,不能产生I/O流,它的唯一作用就是接收和发送数据报包,这个数据报包在Java中是使用DatagramPacket对象实现的。
数据报套接字编程中主要使用下面三个类:DatagramPacket 、DatagramSocket和MulticastSocket。
- DatagramPacket对象描绘了自寻址包的地址信息;
- DatagramSocket表示客户端程序与服务器程序自寻址套接字;
- MulticastSocket 描绘了能进行多点传送的自寻址套接字。
二 DatagramPacket
2.1 创建DatagramPacket对象
2.1.1 创建的DatagramPacket对象用于接收数据
以一个空数组来创建DatagramPacket对象,该对象的作用是接收DatagramSocket中的数据。
- public DatagramPacket(byte buf[], int length) :接收到的数据从buf[0]开始存放,直到整个数据包接收完毕或者将length的字节写入buf为止。
- public DatagramPacket(byte buf[], int offset, int length):接收到的数据从buf[offset]开始存放,如果数据包长度超出了length,则会触发IllegalArgument-Exception。
不过这是RuntimeException,不需要用户代码捕获。
示范代码如下:
byte[] buffer = new byte[8912];
DatagramPacket datap = new DatagramPacket(buffer, buffer.length);
2.1.2 创建的DatagramPacket对象用于发送数据##
以一个包含数据的数组 buf[]来创建DatagramPacket对象,该对象作为DatagramSocket发送数据的载体,并指定该DatagramPacket目的IP地址和端口号。
- public DatagramPacket(byte buf[], int length, InetAddress address, int port)
- public DatagramPacket(byte buf[], int offset, int length, InetAddress address, int port)
示范代码是要发送一串字符串:
String string = new String("java networking");
byte[] data=string.getBytes();
int port=1024;
InetAddress inetA=null;
try {
inetA = InetAddress.getByName("127.0.0.1");
DatagramPacket datap = new DatagramPacket(data,data.length,inetA,port);
} catch (UnknownHostException e) {}
2.2 DatagramPacket常用方法
获取DatagramPacket对象属性的方法如下:
- public synchronized InetAddress getAddress()
- public synchronized int getPort()
- public synchronized byte[] getData()
- public synchronized int getLength()
- public synchronized int getOffset()
设置DatagramPacket对象属性的方法如下:
- public synchronized void setAddress(InetAddress iaddr)
- public synchronized void setPort(int iport)
- public synchronized void setData(byte[] buf, int offset, int length)
- public synchronized void setData(byte[] buf)
- public synchronized void setLength(int length)
- public synchronized void setSocketAd