缓冲区:
属性:
1:容量:(capacity)容纳数据的量。
2:极限(limit):表示缓冲区的当前的终点,不能对超过极限的区域进行读写操作(但是可以修改)。
3:位置:(position):表示缓冲区中下一个读写单元的位置,每次读写都会改变。为下一个数据读写准备,是非负数。不应该大于极限。
用于改变三个属性的方式:
clear():把极限设为容量,再把位置设为0
flip():把极限设为位置,再把位置设为0
rewind():不改变极限,把位置设为0
其他方法:
remaining ()方法返回缓冲区的剩余容量。
allocate():返回一个ByteBuffer对象,参数指定缓冲区的大小
Channel:通道
用来连接缓冲区与数据汇(数据目的地)
Channel中有两个重要的接口ReadableChannel和WriteableChannel
ReadableChannel:
声明了read(ByteBuffer str):把数据源的数据读到指定的ByteBuffer中
write(ByteBuffer str):把指定字节缓冲区的数据写入数据汇。
注意:
在使用read()时,ByteBuffer的位置为p 剩余容量为(limit-p)为r,假如读了n个字节, 在阻塞模式下read()会争取读到r个字节,如果输入流中不足r个字节,就进入阻塞状态,直到输入到了r个字节,或者读入了r个字节,或者i/o异常。
在非阻塞模式下 read()原则是度多少数据就读多少数据,read()读取管道中的数据后会立即返回,不论是有还是没有数据。
write()方法与read的原理一样。
有时在使用UDP进行信息传输的时候需要进行编码与解码
字节编码(CharSet)
把字节序列转化为字符串的序列称为解码,把字符串转化为字节序列称为编码。
CharSet类提供了如下方法:
ByteBuffer encode(String str):对参数指定的字符串进行编码,并将其存放在一个ByteBuffer对象中。
ByteBufferencode (CharBuffer cb):对字符缓冲区中的字符进行编码,把得到的字节序列放在ByteBuffer序列中。
可以通过forName(String , encode)指定编码类型。
具体实现如下:
发送数据端:
public class CharSetChannelSend {
private static DatagramChannel channel= null;
private static DatagramSocket socket= null;
private static InetSocketAddress address= null;
private static InetSocketAddress localAdress = null;
public static void main(String[] args) throws IOException, InterruptedException {
sender () ;
}
public static void sender () throws IOException, InterruptedException {
channel = DatagramChannel.open();
socket= channel.socket();
localAdress= new InetSocketAddress(7000);
address= new InetSocketAddress(InetAddress.getByName("localhost"),8000);
socket.bind(localAdress);
socket.connect(InetAddress.getByName("localhost"), 8000);
ByteBuffer br = ByteBuffer.allocate(1024);
boolean flag = true;
String info ="离离原上草,一岁一枯荣";
br.clear();
while (flag) {
channel.send(ByteBuffer.wrap(info.getBytes()), address);
System.out.println("数据已发送");
Thread.sleep(3000);
}
socket.close();
}
}
接收端:
public class CharsetChannelReceive {
private static DatagramChannel channel = null;
private static DatagramSocket socket = null;
private static InetSocketAddress address= null;
public static void main(String[] args) throws IOException, InterruptedException {
receive ();
}
public static void receive () throws IOException, InterruptedException{
channel= DatagramChannel.open();
socket = channel.socket();
address = new InetSocketAddress(8000);
socket.bind(address);
System.out.println("已连接服务器");
ByteBuffer br = ByteBuffer.allocate(1024);
boolean flag = true;
while (flag) {
channel.receive(br);
br.clear();
String info = Charset.forName("GBK").decode(br).toString();
System.out.println(info);
Thread.sleep(3000);
}
socket.close();
}
}