您的位置:首页 > 理论基础 > 计算机网络

java网络编程学习(四)UDP/IP+BIO/NIO/多播

2011-11-07 15:49 656 查看
UDP是无连接的,尽最多努力的,面向报文的网络传输层协议。

Java对UDP/IP方式的网络数据通信采用的仍然是Socket机制。UDP的Socket是无连接的,要进行双向的通信,需要两端都成为UDP服务器端。

Java中使用DatagramSocket和DatagramPocket来实现UDP+BIO模式的网络交互。

DatagramSocket负责监听端口及读写数据流。DatagramPacket作为数据流对象进行传输。

通常实现代码如下:

DatagramSocketserverSocket=new DatagramSocket(PORT);
byte[] buffer=new byte[65535];
DatagramPacket receivePacket=new DatagramPacket(buffer,buffer.length);

byte[] datas=new byte[]{0,1,0,1};
InetAddress server=Inet4Address.getLocalHost();
DatagramSocket socket=new DatagramSocket();
DatagramPacket packet=new DatagramPacket(datas,datas.length,server,PORT);
//阻塞发送packet到指定的服务器和端口,当网络IO出现异常时抛出IOException,
//当连接不上目标地址和端口抛出PortUnreachableException
socket.send(packet);

//阻塞并同步读读取流信息,如接收到的流信息比packet长度长,则删除更长的信息,
//可以通过setSoTimeout()方法设置读取流的超时时间。
serverSocket.receive(receivePacket);


以上是一个UDP端得实现代码,客户端和服务器端实现均类似。

对于客户端,UDP无需建立连接,因此没有TCP/IP通信连接竞争的问题。但存在,最终流读写问题,读写数据流是同步的,阻塞的。

对于服务器端,同时接受多个请求,可以对发送过来的一个DatagramPacket放到一个线程中进行处理。

UDP+NIO

类似的,在java中可以通过DatagramChannle和ByteBuffer类来实现UDP+NIO方式的通信。

DatagramChannel可以负责监听端口和进行读/写操作。ByteBuffer用于数据传输。基于这两个类实现主要代码如下:

//接收流数据
DatagramChannelreceiveChannel=DatagramChannel.open();
receiveChannel.configureBlocking(false);
DatagramSocketsocket=receiveChannel.socket();
socket.bind(new InetSocketAddress(LOCAL_HOST,receivePort));
Selector selector=Selector.open();
receiveChannel.register(selector,SelectionKey.OP_READ);
//类似TCP+NIO方式对selector中的SelectionKey进行遍历,读取流信息

//发送流数据
DatagramChannelsendChannel=DatagramChannel.open();
sendChannel.configureBlocking(false);
SocketAddress addr=new InetSocketAddress(LOCAL_HOST,sendPort);
sendChannel.connect(addr);
//阻塞写入数据,如发送缓存区已满,返回0,此时可通过注册SelectionKey.OP_WRITE
//事件,以便在可写入时,在进行写操作.代码略。
sendChannel.write(byteBufferData);


NIO中,只有在有数据Buffer读取或可写入buffer数据时才做相应的IO操作,而不用阻塞当前线程。

前面的TCP+BIO,TCP+NIO,UDP+BIO,UDP+NIO,谈到的都是一对一的网络通信。在实际情况中,经常存在要将消息发送到多台机器。对于这种情况,

第一种方案,显然很容易想到,使用多个连接建立,发送多个数据信息,这时发送方显然可能面临较大的发送压力,尤其是传输视频数据的时候。

在计算机网络课程中,有IP多播内容。在一对多的通信中,多播只需要发送一份多播数据报,并且只发送一次即可,可大大节省网络资源。《计算机网络》, 谢希仁P164。

在java中,可基于MulticastSocket和DatagramPacket实现多播网络通信。MulticastSocket继承于DatagramSocket,它能基于UDP/IP实现多播方式的网络通信。在多播通信中,不同的地方在于接收数据端通过加入多播组来进行数据的接收,同样发送数据端也要求加入到多播组进行发送。多播组使用D类IP地址,其范围为:224.0.0.0~239.2555.255.255。每一个D类地址标志一个多播组。基于多播实现网络通信代码如下:

InetAddress groupAddress=InetAddress.getByName("224.0.0.1");
MulticastSocket server=new MulticastSocket(port);
//加入多播组,如果地址为非多播地址,抛出IOException,当不希望在发送
//或读取数据到多播地址时,可通过调用server.leaveGroup(多播地址),离开多播
server.joinGroup(groupAddress);

//发送Socket
MulticastSocket sendSocket=new MulticastSocket();
sendSocket.joinGroup(groupAddress);

//然后,可通过UDP+BIO方式,使用receive和send进行读/写操作


在java应用中,多播多用于多台机器之间状态的同步。使用多播的java项目:JGroup.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: