今天有人问我Netty的UDP怎么使用,我自己尝试的去写一个Demo,在网上搜索了一下,关于Netty的UDP实现还是很少的,所以,今天写下这篇文章用来记录今天的一个简单Demo实现

不使用Netty的UDP实例:

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应该是不存在粘包问题,拆包问题同样就没有了。

Netty实现UDP的案例,

NettyUdpServer.java

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.java

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方面的问题,一起进步。

Java NIO UDP DEMO的更多相关文章

  1. JAVA NIO udp 实现 群转发

    场景很简单,就是多个客户端通过udp,连接到服务器(其实是无连接的,就是服务器保存了客户端的ip信息).然后通过udp协议先服务器发送消息,然后服务器在通过udp转发在各个客服端. 这个是不是 观察者 ...

  2. JAVA NIO异步通信框架MINA选型和使用的几个细节(概述入门,UDP, 心跳)

    Apache MINA 2 是一个开发高性能和高可伸缩性网络应用程序的网络应用框架.它提供了一个抽象的事件驱动的异步 API,可以使用 TCP/IP.UDP/IP.串口和虚拟机内部的管道等传输方式.A ...

  3. 使用JAVA NIO实现的UDP client和server

    //////////////////////////////////////////////////////////////////////////////////////////////////// ...

  4. Java NIO网络编程demo

    使用Java NIO进行网络编程,看下服务端的例子 import java.io.IOException; import java.net.InetAddress; import java.net.I ...

  5. 快学Java NIO

    Java NIO Tutorial 地址:http://tutorials.jenkov.com/java-nio/index.html Java NIO系列教程译文地址:http://ifeve.c ...

  6. Java NIO的探究

    1.Java NIO与阻塞IO的区别 阻塞IO通信模型(在上一篇<J2SE网络编程之 TCP与UDP>博客中有所介绍) 我们知道阻塞I/O在调用InputStream.read()方法时是 ...

  7. Java - NIO基础

    1. 概述 现在使用NIO的场景越来越多,很多技术框架都使用NIO技术,比如Tomcat,Jetty,Netty等. 传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer进行操 ...

  8. 史上最强Java NIO入门:担心从入门到放弃的,请读这篇!

    本文原题“<NIO 入门>,作者为“Gregory M. Travis”,他是<JDK 1.4 Tutorial>等书籍的作者. 1.引言 Java NIO是Java 1.4版 ...

  9. java NIO面试题剖析

    转载:https://mp.weixin.qq.com/s/YIcXaH7AWLJbPjnTUwnlyQ 首先我们分别画图来看看,BIO.NIO.AIO,分别是什么? BIO:传统的网络通讯模型,就是 ...

随机推荐

  1. 跨服务器导入数据SQL语句及其问题解决方案

    --跨服务器导入数据SQL语句: insert into [shsw_manager].[dbo].[Station_List]select * from OPENROWSET('SQLOLEDB', ...

  2. javascript 判断身份证的正确性

    function isIdCardNo(vals) { var cardNum = vals; if (cardNum.length == 0) { return true; } // 11-15,2 ...

  3. Floyd 算法的动态规划本质

    [转载自:http://www.cnblogs.com/chenying99/p/3932877.html] Floyd–Warshall(简称Floyd算法)是一种著名的解决任意两点间的最短路径(A ...

  4. 李明杰视频 SVN

    李明杰视频 SVN 就10-12使用技术SVN 源代码会引发哪些问题? 无法后悔:做错一个操作 版本备份:费控件,费时间 版本混乱:因版本备份太多造成混乱 代码冲突:多人操作同一文件 强烈建议 使用源 ...

  5. UVa 10561 - Treblecross

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  6. mac 连接mysql提示 Warning: mysqli::real_connect(): (HY000/2002): No such file or directory

    mac 连接mysql的时候提示 Warning: mysqli::real_connect(): (HY000/2002): No such file or directory [说明1]MAC下M ...

  7. form v

    <form name="example_form" action="http://google.com" method="POST"& ...

  8. Oracle性能调优

    这部分目前主要是从网上搜集来的,后续要在实践中慢慢体会. v$sqltext: 存储的是被分割的sql v$sqlarea: 存储的是完整的sql和一些统计信息,比如累计的执行次数.逻辑读.物理读等( ...

  9. 【模拟题(电子科大MaxKU)】解题报告【树形问题】【矩阵乘法】【快速幂】【数论】

    目录: 1:一道简单题[树形问题](Bzoj 1827 奶牛大集会) 2:一道更简单题[矩阵乘法][快速幂] 3:最简单题[技巧] 话说这些题目的名字也是够了.... 题目: 1.一道简单题 时间1s ...

  10. HTML5中canvas的save和restore方法

    canvas的save和restore方法: save() 方法把当前绘画状态的一份拷贝压入到一个保存图像状态的栈中.这里的绘画状态指坐标原点.变形时的变化矩阵(该矩阵是调用 rotate().sca ...