软件编程
位置:首页>> 软件编程>> java编程>> Java NIO实例UDP发送接收数据代码分享

Java NIO实例UDP发送接收数据代码分享

作者:在远行的路上  发布时间:2022-12-03 01:30:37 

标签:java,nio,udp

Java的NIO包中,有一个专门用于发送UDP数据包的类:DatagramChannel,UDP是一种无连接的网络协议,
一般用于发送一些准确度要求不太高的数据等。

完整的服务端程序如下:


public class StatisticsServer {
 //每次发送接收的数据包大小
 private final int MAX_BUFF_SIZE = 1024 * 10;
 //服务端监听端口,客户端也通过该端口发送数据
 private int port;
 private DatagramChannel channel;
 private Selector selector;
 private ScheduledExecutorService es = Executors.newScheduledThreadPool(1);
 public void init() throws IOException {
   //创建通道和选择器
   selector = Selector.open();
   channel = DatagramChannel.open();
   //设置为非阻塞模式
   channel.configureBlocking(false);
   channel.socket().bind(new InetSocketAddress(port));
   //将通道注册至selector,监听只读消息(此时服务端只能读数据,无法写数据)
   channel.register(selector, SelectionKey.OP_READ);
   //使用线程的方式,保证服务端持续等待接收客户端数据
   es.scheduleWithFixedDelay(new Runnable() {
     @Override
     public void run() {
       try {
         while(selector.select() > 0) {
           Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
           while(iterator.hasNext()) {
             SelectionKey key = iterator.next();
             try {
               iterator.remove();
               if(key.isReadable()) {
                 //接收数据
                 doReceive(key);
               }
             } catch (Exception e) {
               logger.error("SelectionKey receive exception", e);
               try {
                 if (key != null) {
                   key.cancel();
                   key.channel().close();
                 }
               } catch (ClosedChannelException cex) {
                 logger.error("Close channel exception", cex);
               }
             }
           }
         }
       } catch (IOException e) {
         logger.error("selector.select exception", e);
       }
     }
   }, 0L, 2L, TimeUnit.MINUTES);
 }
 //处理接收到的数据
 private void doReceive(SelectionKey key) throws IOException {
   String content = "";
   DatagramChannel sc = (DatagramChannel) key.channel();
   ByteBuffer buffer = ByteBuffer.allocate(MAX_BUFF_SIZE);
   buffer.clear();
   sc.receive(buffer);
   buffer.flip();
   while(buffer.hasRemaining()) {
     byte[] buf = new byte[buffer.limit()];
     buffer.get(buf);
     content += new String(buf);
   }
   buffer.clear();
   logger.debug("receive content="+content);
   if(StringUtils.isNotBlank(content)) {
     doSave(content);
   }
 }
}

客户端发送完整例子如下:


DatagramChannel channel = DatagramChannel.open();

StringBuilder sb = new StringBuilder();
   sb.append("2017-03-09 12:30:00;")
       .append("aaa")
       .append("testapp;")
       .append("test.do;")
       .append("param=hello;")
       .append("test;")
       .append("100;")
       .append("1");
   ByteBuffer buffer = ByteBuffer.allocate(10240);
   buffer.clear();
   buffer.put(sb.toString().getBytes());
   buffer.flip();
   //此处IP为服务端IP地址,端口和服务端的端口一致
   int n = channel.send(buffer, new InetSocketAddress("127.0.0.1", 8080));
   System.out.println(n);
   //每次数据发送完毕之后,一定要调用close方法,来关闭占用的udp端口,否则程序不结束,端口不会释放
   channel.close();

总结

Rxjava功能操作符的使用方法详解

分享一个简单的java爬虫框架

Javaweb应用使用限流处理大量的并发请求详解

有什么问题可以随时留言,小编会及时回复大家的。感谢朋友们对本站的支持!

来源:http://blog.csdn.net/lzy_lizhiyang/article/details/61914581

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com