java NIO实现UDP通讯
NIO Udp通讯工具类
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.Iterator;import lombok.extern.slf4j.Slf4j;/*** NIO Udp工具类*/
@Slf4j
public class MyUdpSocket {//获取报文的通道private DatagramChannel channel;//多路复用选择器private Selector selector;private final int MAX_SIZE = 1280;//当前获取到版本的端口private int client_port;//记录当前获取到报文的ipprivate String client_ip;ByteBuffer receive_buffer = ByteBuffer.allocate(MAX_SIZE);public MyUdpSocket(String ip, int port) throws IOException {channel=DatagramChannel.open();selector=Selector.open();try{//调整此通道为非阻塞模式 channel.configureBlocking(false); //获取与套接字通道关联的套接字,并将该套接字绑定到本机指定端口 channel.socket().bind(new InetSocketAddress(port));//为通道选择器注册通道,并指定操作的选择键集 channel.register(selector, SelectionKey.OP_READ); }catch (IOException e) {log.error("MyUdpSocket init error", e);}}/*** 接收数据* @return*/public final int receive() {try{receive_buffer.clear();if(selector.select(1000)!=0) {Iterator<SelectionKey> itr = selector.selectedKeys().iterator();while(itr.hasNext()){ SelectionKey key = itr.next( );itr.remove(); if(key.isReadable()){DatagramChannel dc = (DatagramChannel)key.channel(); InetSocketAddress client = (InetSocketAddress)dc.receive(receive_buffer); //接收来自任意一个Client的数据报if (client!=null) {client_ip=client.getAddress().getHostAddress();client_port=client.getPort();//System.out.println(client_ip+":"+client_port+" size="+receive_buffer.position());key.interestOps(SelectionKey.OP_READ);return receive_buffer.position();} else {return 0;}} else {return 0;}}}}catch (IOException e) {log.error(String.format("udp_receive出错:%s", e.getMessage()), e);}return 0;}public final void close() throws IOException {selector.close();channel.close();}public final int get_client_port(){return client_port;}public final String get_client_ip(){return client_ip;}public final byte[] get_receive_packet(int size){byte[] packet = new byte[size];for (int i=0; i<size; i++){packet[i]=receive_buffer.array()[i];}return packet;}public final void get_receive_buffer(byte[] buffer){receive_buffer.get(buffer);}
}
用法:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;public class UdpSocketTest {public static void main(String[] args) throws IOException {MyUdpSocket socket = new MyUdpSocket("127.0.0.1", 1234);while(true) {int size = socket.receive();if (size>0) {byte[] data = socket.get_receive_packet(size);System.out.println("ip:" + socket.get_client_ip());DatagramPacket packet = new DatagramPacket(data, 0, data.length);packet.setSocketAddress(new InetSocketAddress(socket.get_client_ip(), socket.get_client_port()));DatagramSocket datagramSocket = new DatagramSocket(null);datagramSocket.setReuseAddress(true);datagramSocket.send(packet);datagramSocket.close();}}}
}