今天有人問我Netty的UDP怎麼使用,我本身嘗試的去寫一個Demo,在網上搜索了一下,關於Netty的UDP實現仍是不多的,因此,今天寫下這篇文章用來記錄今天的一個簡單Demo實現java
不使用Netty的UDP實例:bootstrap
UdpServer.java數組
package com.rainy.netty.udp02; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; /** * Created by smzdm on 16/8/10. */ public class UdpServer { public static final int PORT = 30000; // 定義每一個數據報的最大大小爲4KB private static final int DATA_LEN = 4096; // 定義接收網絡數據的字節數組 byte[] inBuff = new byte[DATA_LEN]; // 以指定字節數組建立準備接收數據的DatagramPacket對象 private DatagramPacket inPacket = new DatagramPacket(inBuff, inBuff.length); // 定義一個用於發送的DatagramPacket對象 private DatagramPacket outPacket; // 定義一個字符串數組,服務器端發送該數組的元素 String[] books = new String[] { "瘋狂Java講義", "輕量級Java EE企業應用實戰", "瘋狂Android講義", "瘋狂Ajax講義" }; public void init() throws IOException { try { // 建立DatagramSocket對象 DatagramSocket socket = new DatagramSocket(PORT); // 採用循環接收數據 for (int i = 0; i < 1000; i++) { // 讀取Socket中的數據,讀到的數據放入inPacket封裝的數組裏 socket.receive(inPacket); // 判斷inPacket.getData()和inBuff是不是同一個數組 System.out.println(inBuff == inPacket.getData()); // 將接收到的內容轉換成字符串後輸出 System.out.println(new String(inBuff , 0, inPacket.getLength())); // 從字符串數組中取出一個元素做爲發送數據 byte[] sendData = books[i % 4].getBytes(); // 以指定的字節數組做爲發送數據,以剛接收到的DatagramPacket的 // 源SocketAddress做爲目標SocketAddress建立DatagramPacket outPacket = new DatagramPacket(sendData , sendData.length, inPacket.getSocketAddress()); // 發送數據 socket.send(outPacket); } } catch (Exception e) { System.out.println(e.getMessage()); } } public static void main(String[] args) throws IOException { new UdpServer().init(); } }
UdpClient.java緩存
package com.rainy.netty.udp02; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.Scanner; /** * Created by smzdm on 16/8/10. */ public class UdpClient { // 定義發送數據報的目的地 public static final int DEST_PORT = 30000; public static final String DEST_IP = "127.0.0.1"; // 定義每一個數據報的最大大小爲4KB private static final int DATA_LEN = 4096; // 定義接收網絡數據的字節數組 byte[] inBuff = new byte[DATA_LEN]; // 以指定的字節數組建立準備接收數據的DatagramPacket對象 private DatagramPacket inPacket = new DatagramPacket(inBuff, inBuff.length); // 定義一個用於發送的DatagramPacket對象 private DatagramPacket outPacket = null; public void init() throws IOException { try { // 建立一個客戶端DatagramSocket,使用隨機端口 DatagramSocket socket = new DatagramSocket(); // 初始化發送用的DatagramSocket,它包含一個長度爲0的字節數組 outPacket = new DatagramPacket(new byte[0], 0 , InetAddress.getByName(DEST_IP), DEST_PORT); // 建立鍵盤輸入流 Scanner scan = new Scanner(System.in); // 不斷地讀取鍵盤輸入 while (scan.hasNextLine()) { // 將鍵盤輸入的一行字符串轉換成字節數組 byte[] buff = scan.nextLine().getBytes(); // 設置發送用的DatagramPacket中的字節數據 outPacket.setData(buff); // 發送數據報 socket.send(outPacket); // 讀取Socket中的數據,讀到的數據放在inPacket所封裝的字節數組中 socket.receive(inPacket); System.out.println(new String(inBuff, 0 , inPacket.getLength())); } } catch (Exception e) { System.out.println(e.getMessage()); } } public static void main(String[] args) throws IOException { new UdpClient().init(); } }
這兩段代碼是在網上搜羅的例子,服務器
原文路徑:http://blog.csdn.net/jiangxinyu/article/details/8161044網絡
在這個例子中,咱們能夠看到,UDP的實現方式和TCP的實現方式上是不一樣的,UDP的實如今於,發送數據包,後面我也在網上查看了一些問題,關於粘包問題,我發現,網上部分說UDP有粘包問題,部分說沒有UDP粘包問題,就算有也是不多量的不容易出現的問題,其實,我偏向於UDP沒有粘包問題,由於UDP自己是按包發送,並且,UDP和TCP不同,UDP是包完整就發送,而TCP在包完整的狀況下,會判斷是否值得發送,有發送緩存的實現,因此,綜合分析,我以爲UDP應該是不存在粘包問題,拆包問題一樣就沒有了。socket
Netty實現UDP的案例,ide
NettyUdpServer.javaoop
package com.rainy.netty.udp01;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
/**
* Created by smzdm on 16/8/10.
*/
public class NettyUdpServer {
public static void main(String[] args) throws InterruptedException {
Bootstrap b = new Bootstrap();
EventLoopGroup group = new NioEventLoopGroup();
b.group(group)
.channel(NioDatagramChannel.class)
.option(ChannelOption.SO_BROADCAST, true)
.handler(new UDPSeverHandler());
b.bind(9000).sync().channel().closeFuture().await();
}
}
class UDPSeverHandler extends SimpleChannelInboundHandler<DatagramPacket> {
@Override
protected void messageReceived(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
ByteBuf buf = (ByteBuf) packet.copy().content();
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, "UTF-8");
System.out.println(body);
}
@Override
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
super.channelRegistered(ctx);
System.out.println("I got it!");
}
}
NettyUdpClient.javaui
package com.rainy.netty.udp; import java.net.InetSocketAddress; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.DatagramPacket; import io.netty.channel.socket.nio.NioDatagramChannel; import io.netty.util.CharsetUtil; /** * Created by smzdm on 16/8/10. */ public class NettyUdpClient { public static void main(String[] args) { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group).channel(NioDatagramChannel.class) .option(ChannelOption.SO_BROADCAST,true) .handler(new UdpClientHandler()); Channel ch = b.bind(0).sync().channel(); // 向網段類全部機器廣播發UDP ch.writeAndFlush( new DatagramPacket( Unpooled.copiedBuffer("發送第一個UDP", CharsetUtil.UTF_8), new InetSocketAddress("127.0.0.1", 9000))).sync(); if(!ch.closeFuture().await(15000)){ System.out.println("查詢超時!!!"); } } catch (Exception e) { System.out.println(e.getMessage()); } finally { group.shutdownGracefully(); } } } class UdpClientHandler extends SimpleChannelInboundHandler<DatagramPacket> { @Override public void messageReceived(ChannelHandlerContext channelHandlerContext, DatagramPacket datagramPacket) throws Exception { String response = datagramPacket.content().toString(CharsetUtil.UTF_8); if(response.startsWith("結果:")){ System.out.println(response); channelHandlerContext.close(); } } @Override public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause)throws Exception{ ctx.close(); cause.printStackTrace(); } }
netty對應原文路徑:http://www.tuicool.com/articles/Rry6biF
上面的例子做爲參考進行的代碼處理,發現這樣就能使得代碼正常發送,若是你須要獲取對應的發送端的IP地址,那麼,你可使用
packet.sender().getAddress().getHostAddress();進行獲取發送端IP地址,本質上來講,這個UDP通常都是基於使用UDP的方式進行自定義協議方式實現業務功能,具體能夠根據本身的文檔格式進行對應的解析。這個方式,若是作過銀行接口的,應該對這個接口實現方式有必定的認識。本文暫時先寫到這裏,若是有什麼問題,請留言。你們一塊兒交流討論NIO方面的問題,一塊兒進步。