JAVA NIO DatagramChannel

DatagramChannel - a channel for UDP datagrams

The DatagramChannel in Java NIO is a channel that can send and receive UDP packets.

Steps:

 Open DatagramChannel
 Receive/send data

Some steps in the usage are similar to SocketChannel, see the previous blog for details, I will not explain it here.

It should be noted that, in UDP non-blocking network, the receiver and sender of the information in NIO directly use the open method of DatagramChannel to generate a datagram channel, and specify the address and port when sending; the receiver needs to bind a port number first, monitoring. The receiver may listen to multiple senders sending data to it. In order for a single thread to process data sent by multiple clients, and not be blocked by a sender during the sending process, a selector is also required.

Using a selector still requires registering the channel with the selector and specifying the event to be listened for, that is, the selection key.

code example

package com.happybks.nio.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;

import org.junit.Test;

public class TestNonBlockingNIO2 {

	@Test
	public void send() throws IOException{
		DatagramChannel datagramChannel = DatagramChannel.open();
		datagramChannel.configureBlocking(false);
		
		ByteBuffer buf = ByteBuffer.allocate(1024);
		
		Scanner scanner = new Scanner(System.in);
		while(scanner.hasNext()){
			String inputStr=scanner.next();
			buf.put((new Date().toString()+":\n"+inputStr).getBytes());
			buf.flip();
			datagramChannel.send(buf, new InetSocketAddress("127.0.0.1", 8888));
			buf.clear();
		}
		
		scanner.close();
		datagramChannel.close();
	}
	
	@Test
	public void receive() throws IOException{
		DatagramChannel datagramChannel = DatagramChannel.open();
		datagramChannel.configureBlocking(false);

		datagramChannel.bind(new InetSocketAddress(8888));
		
		Selector selector = Selector.open();
		datagramChannel.register(selector, SelectionKey.OP_READ);
		
		while(selector.select()>0){
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			
			while(iterator.hasNext()){
				SelectionKey selectionKey=iterator.next();
				if(selectionKey.isReadable()){
					ByteBuffer buf = ByteBuffer.allocate(1024);
					datagramChannel.receive(buf);
					buf.flip();
					System.out.println(new String(buf.array(), 0, buf.limit()));
					buf.clear();
				}
			}
			iterator.remove();
			
		}
		
		
	}
}

One thing I didn't mention last time here is that the selector's select() method has two similar methods.

Select channel by Selector

Once one or more channels are registered with the Selector, several overloaded select() methods can be called. These methods return those channels that are ready for the event you are interested in (such as connect, accept, read, or write). In other words, if you are interested in "read-ready" channels, the select() method will return those channels that are ready for read events.

Here is the select() method:

int select()
int select(long timeout)
int selectNow()
select() blocks until at least one channel is ready for the event you registered for.

select(long timeout) is the same as select(), except that it blocks for a maximum of timeout milliseconds (parameter).

selectNow() does not block and returns immediately no matter what channel is ready. .) .

The int value returned by the select() method indicates how many channels are ready. That is, how many channels have become ready since the last time the select() method was called. If the select() method is called, it returns 1 because one of the channels becomes ready, and if the select() method is called again, it will return 1 again if another channel is ready. If nothing was done on the first ready channel, there are now two ready channels, but between each select() method call, only one channel is ready.

(This article comes from the blog post of oschina blogger happyBKs: https://my.oschina.net/happyBKs/blog/1603680)

operation result

Back to our previous example. Also note the keyIterator.remove() call at the end of each iteration. The Selector does not remove SelectionKey instances from the selected key set by itself. You must remove yourself when you are done processing the channel. The next time the channel becomes ready, the Selector will put it in the selected key set again.

The result of running the program:

We input information on the sender side, and the receiver side immediately receives the information and outputs it.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325363442&siteId=291194637