轉自:https://www.xuebuyuan.com/3215260.html

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.

posted on 2020-04-15 03:21  Sharpest  阅读(371)  评论(0编辑  收藏  举报