DatagramPacket的学习

今天学习了DatagramPacket,这里记录一下

与TCP协议发送和接收字节流不同,UDP终端交换的是一种称为数据报文的自包含(self-contained)信息。这种信息在Java中表示为DatagramPacket类的实例。发送信息时,Java程序创建一个包含了待发送信息的DatagramPacket实例,并将其作为参数传递给DatagramSocket类的send()方法。接收信息时,Java程序首先创建一个DatagramPacket实例,该实例中预先分配了一些空间(一个字节数组byte[]),并将接收到的信息存放在该空间中。然后把该实例作为参数传递给DatagramSocket类的receive()方法。
除传输的信息本身外,每个DatagramPacket实例中还附加了地址和端口信息,其具体含义取决于该数据报文是被发送还是被接收。若是要发送的数据报文, DatagramPacket实例中的地址则指明了目的地址和端口号,若是接收到的数据报文, DatagramPacket实例中的地址则指明了所收信息的源地址。因此,服务器端可以修改接收到的DatagramPacket实例的缓存区内容,再将这个实例连同修改后的信息一起,发回给它的源地址。在DatagramPacket的内部也有length和offset字段,分别定义了数据信息在缓存区的起始位置和字节数。请参考下面的介绍和第2.3.4节的内容,以避免在使用DatagramPackets时易犯的一些错误。
DatagramPacket: 创建

DatagramPacket(byte[ ] data, int length) 
DatagramPacket(byte[ ] data, int offset, int length)
DatagramPacket(byte[ ] data, int length, InetAddress 
remoteAddr, int remotePort) 
DatagramPacket(byte[ ] data, int offset, int length, 
InetAddress remoteAddr, int remotePort) 
DatagramPacket(byte[ ] data, int length, SocketAddress sockAddr)
DatagramPacket(byte[ ] data, int offset, int length, 
SocketAddress sockAddr)
以上构造函数都创建一个数据部分包含在指定的字节数组中的数据报文,前两种形式的构造函数主要用来创建接收的端的DatagramPackets实例,因为没有指定其目的地址(尽管可以通过setAddress() 和setPort()方法,或setSocketAddress()方法来指定)。后四种形式主要用来创建发送端的DatagramPackets实例。
如果指定了offset,数据报文的数据部分将从字节数组的指定位置发送或接收数据。length参数指定了字节数组中在发送时要传输的字节数,或在接收数据时所能接收的最多字节数。length参数可能比data.length小,但不能比它大。
目的地址和端口号可以分别设置,或通过SocketAddress同时设置。
DatagramPacket: 地址处理

InetAddress getAddress() 
void setAddress(InetAddress address) 
int getPort() 
void setPort(int port)
 SocketAddress getSocketAddress()
 void setSocketAddress(SocketAddress sockAddr)
除了构造函数外,以上方法提供了另外一些方法来访问和修改DatagramPacket实例的地址信息。另外需要注意,DatagramSocket的receive()方法是将其地址和端口设置为数据报发送者的地址和端口。
DatagramPacket: 处理数据
int getLength() 
void setLength(int length) 
int getOffset()
byte[ ] getData() 
void setData(byte[ ] data)
void setData(byte[ ] buffer, int offset, int length)

前两个方法返回和设置数据报文中数据部分的内部长度。此内部长度可以通过其构造函数或setLength()方法显式地设定。若试图将其设置得比相关联的缓存区长度更大,程序将抛出一个IllegalArgumentException异常。DatagramSocket类的receive()方法在两个方面使用内部长度:在输入时,用来指定接收到的将被复制到缓冲区的消息的最长字节数,在返回时,用来指示实际存入缓冲区的字节数。
getOffset()方法返回发送或接收的数据存放在缓存区时的偏移量。不存在setOffset()方法,不过可以使用setData()方法来设置偏移量。
getData()方法返回与数据报文相关联的字节数组。实际返回的是对与DatagramPacket最近关联的字节数组的一个引用,而关联则是通过构造函数或setData()方法形成。返回的缓存数组的长度可能比数据报文内部长度更长,因此,必须使用内部长度和偏移量来指定实际接收到的信息。
setData()方法指定一个字节数组作为该数据报文的数据部分。第一种形式将整个字节数组作为缓冲区;第二种形式把字节数组中,从offset到offset+length-1的部分作为缓存区。每次调用第二种形式的setData()方法,都将更新数据的内部偏移量和长度。大笑




  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值