java udp nio_Java NIO UDP DEMO

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

不使用Netty的UDP实例:

UdpServer.java

packagecom.rainy.netty.udp02;importjava.io.IOException;importjava.net.DatagramPacket;importjava.net.DatagramSocket;/*** Created by smzdm on 16/8/10.*/

public classUdpServer {public static final int PORT = 30000;//定义每个数据报的最大大小为4KB

private static final int DATA_LEN = 4096;//定义接收网络数据的字节数组

byte[] inBuff = new byte[DATA_LEN];//以指定字节数组创建准备接收数据的DatagramPacket对象

private DatagramPacket inPacket =

newDatagramPacket(inBuff, inBuff.length);//定义一个用于发送的DatagramPacket对象

privateDatagramPacket outPacket;//定义一个字符串数组,服务器端发送该数组的元素

String[] books = newString[] {"疯狂Java讲义","轻量级Java EE企业应用实战","疯狂Android讲义","疯狂Ajax讲义"};public void init() throwsIOException {try{//创建DatagramSocket对象

DatagramSocket socket = newDatagramSocket(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(newString(inBuff

,0, inPacket.getLength()));//从字符串数组中取出一个元素作为发送数据

byte[] sendData = books[i % 4].getBytes();//以指定的字节数组作为发送数据,以刚接收到的DatagramPacket的//源SocketAddress作为目标SocketAddress创建DatagramPacket

outPacket = newDatagramPacket(sendData

, sendData.length, inPacket.getSocketAddress());//发送数据

socket.send(outPacket);

}

}catch(Exception e) {

System.out.println(e.getMessage());

}

}public static void main(String[] args) throwsIOException {newUdpServer().init();

}

}

UdpClient.java

packagecom.rainy.netty.udp02;importjava.io.IOException;importjava.net.DatagramPacket;importjava.net.DatagramSocket;importjava.net.InetAddress;importjava.util.Scanner;/*** Created by smzdm on 16/8/10.*/

public classUdpClient {//定义发送数据报的目的地

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 =

newDatagramPacket(inBuff, inBuff.length);//定义一个用于发送的DatagramPacket对象

private DatagramPacket outPacket = null;public void init() throwsIOException {try{//创建一个客户端DatagramSocket,使用随机端口

DatagramSocket socket = newDatagramSocket();//初始化发送用的DatagramSocket,它包含一个长度为0的字节数组

outPacket = new DatagramPacket(new byte[0], 0, InetAddress.getByName(DEST_IP), DEST_PORT);//创建键盘输入流

Scanner scan = newScanner(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) throwsIOException {newUdpClient().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 {

@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

packagecom.rainy.netty.udp;importjava.net.InetSocketAddress;importio.netty.bootstrap.Bootstrap;importio.netty.buffer.Unpooled;importio.netty.channel.Channel;importio.netty.channel.ChannelHandlerContext;importio.netty.channel.ChannelOption;importio.netty.channel.EventLoopGroup;importio.netty.channel.SimpleChannelInboundHandler;importio.netty.channel.nio.NioEventLoopGroup;importio.netty.channel.socket.DatagramPacket;importio.netty.channel.socket.nio.NioDatagramChannel;importio.netty.util.CharsetUtil;/*** Created by smzdm on 16/8/10.*/

public classNettyUdpClient {public static voidmain(String[] args) {

EventLoopGroup group= newNioEventLoopGroup();try{

Bootstrap b= newBootstrap();

b.group(group).channel(NioDatagramChannel.class)

.option(ChannelOption.SO_BROADCAST,true)

.handler(newUdpClientHandler());

Channel ch= b.bind(0).sync().channel();//向网段类所有机器广播发UDP

ch.writeAndFlush(newDatagramPacket(

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{

@Overridepublic voidmessageReceived(ChannelHandlerContext channelHandlerContext,

DatagramPacket datagramPacket)throwsException {

String response=datagramPacket.content().toString(CharsetUtil.UTF_8);if(response.startsWith("结果:")){

System.out.println(response);

channelHandlerContext.close();

}

}

@Overridepublic void exceptionCaught(ChannelHandlerContext ctx,Throwable cause)throwsException{

ctx.close();

cause.printStackTrace();

}

}

netty对应原文路径:http://www.tuicool.com/articles/Rry6biF

上面的例子作为参考进行的代码处理,发现这样就能使得代码正常发送,如果你需要获取对应的发送端的IP地址,那么,你可以使用

packet.sender().getAddress().getHostAddress();

进行获取发送端IP地址,本质上来说,这个UDP一般都是基于使用UDP的方式进行自定义协议方式实现业务功能,具体可以根据自己的文档格式进行对应的解析。这个方式,如果做过银行接口的,应该对这个接口实现方式有一定的认识。

本文暂时先写到这里,如果有什么问题,请留言。大家一起交流讨论NIO方面的问题,一起进步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值