netty 回调+udp通信

1 篇文章 0 订阅
1 篇文章 0 订阅

1、定义Callback接口

package eco.data.m3.supernode.udp;

public interface Callback {

    void onMessage(String content);

    void onFault(String reason);
}

2.定义客户端

package eco.data.m3.supernode.udp;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//import java.net.DatagramPacket;
import java.awt.image.BufferedImageFilter;
import java.net.InetSocketAddress;
import java.lang.String;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Random;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class Client {
    private static Logger logger = LoggerFactory.getLogger(Client.class);

    public static final int MessageReceived = 0x99;
    private int scanPort;

    private HashMap<Integer, Callback> callbackHashMap = new HashMap<>();

    Channel channel;

    public Client(int scanPort) {
        this.scanPort = scanPort;
        init();
    }

    private void init(){

        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        b.group(group)
                .channel(NioDatagramChannel.class)
                .option(ChannelOption.SO_BROADCAST, true)

                .handler(new ClientHandler(this));

        try {
            channel = b.bind(scanPort).sync().channel();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private class ClientHandler extends SimpleChannelInboundHandler<DatagramPacket> {

        Client client;

        public ClientHandler(Client client) {
            this.client = client;
        }

        @Override
        protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg0) throws Exception {
            byte[] resp =new byte[45];
            msg0.content().readBytes(resp);
            int convId=byteArrayToInt(subBytes(resp,0,4));
            System.out.println(convId);
            int SrcPort=byteArrayToInt(subBytes(resp,4,4));
            int DesPort=byteArrayToInt(subBytes(resp,8,4));
            String SrcIp=new String(subBytes(resp,12,12), "utf-8");
            String DestIp=new String(subBytes(resp,24,12), "utf-8");
            String data0=new String(subBytes(resp,40,5), "utf-8");
            System.out.println(SrcPort);
            System.out.println(DesPort);
            System.out.println(SrcIp);
            System.out.println(DestIp);
            System.out.println(data0);

            Callback callback = client.getCallbackHashMap().get(convId);

            if (callback==null){
                ///
                // reply
               // sendPackage(msg0)
                // forward
            }else {
                callback.onMessage("sd");
            }

//            if(response.startsWith("结果:")){
//                System.out.println(response);
//                ctx.close();
//            }
        }
    }

    public void sendPackage(int convId,String data,int SrcPort,int DesPort,String SrcIp,String DestIp ,int nextPort, Callback callback) {
        try {
            //System.out.println(convId);
            Udp_Message_Test msg=new Udp_Message_Test(0,0,0,null,null,null);
            msg.setconvId(convId);
            msg.setSrcPort(SrcPort);
            msg.setDesPort(DesPort);
            msg.setSrcIp(SrcIp);
            msg.setDestIp(DestIp);
            msg.setContent(data);

            byte[] data_buf=con_byte(msg.getContent(),msg.getconvId(),msg.getSrcPort(),msg.getDesPort(),msg.getSrcIp(),msg.getDestIp() ,nextPort);
            //DatagramPacket dp = new DatagramPacket( Unpooled.copiedBuffer("hello!!!", CharsetUtil.UTF_8), new InetSocketAddress("10.108.78.53", scanPort));//不同节点这句需要修改(可能需要加判断)
//            ByteBuf  buff = (ByteBuf) data_buf;//需要字节数组转ByteBuf
            ByteBuf  buff = Unpooled.buffer(16);
           // buff.writeInt(scanPort);
            buff.writeBytes(data_buf);
           // System.out.println(data_buf);
            DatagramPacket dp = new DatagramPacket(buff ,new InetSocketAddress("127.0.0.1", nextPort));//不同节点这句需要修改(可能需要加判断)

            channel.writeAndFlush(dp).sync();

            callbackHashMap.put(convId, callback);
            logger.info("Search, sendPackage()");
           // System.out.println(byteArrayToInt(subBytes(data_buf,0,4)));
        }catch (Exception e){
            e.printStackTrace();
            logger.info("Search, An Error Occur ==>" + e);
        }
    }
    public byte[] con_byte(String data,int convId,int SrcPort,int DesPort,String SrcIp,String DestIp ,int scanPort){
        byte[] buf1 = new byte[4];
        buf1[0] = (byte) ((convId >> 24) & 0xFF);
        buf1[1] = (byte) ((convId >> 16) & 0xFF);
        buf1[2] = (byte) ((convId >> 8) & 0xFF);
        buf1[3] = (byte) (convId & 0xFF);

        byte[] buf2 = new byte[4];
        buf2[0] = (byte) ((SrcPort >> 24) & 0xFF);
        buf2[1] = (byte) ((SrcPort >> 16) & 0xFF);
        buf2[2] = (byte) ((SrcPort >> 8) & 0xFF);
        buf2[3] = (byte) (SrcPort & 0xFF);

        byte[] buf3 = new byte[4];
        buf3[0] = (byte) ((DesPort >> 24) & 0xFF);
        buf3[1] = (byte) ((DesPort >> 16) & 0xFF);
        buf3[2] = (byte) ((DesPort >> 8) & 0xFF);
        buf3[3] = (byte) (DesPort & 0xFF);

        byte[] buf4 = new byte[SrcIp.length()];
        buf4=SrcIp.getBytes();

        byte[] buf5 = new byte[DestIp.length()];
        buf5=DestIp.getBytes();

        byte[] buf6 = new byte[4];
        buf6[0] = (byte) ((scanPort >> 24) & 0xFF);
        buf6[1] = (byte) ((scanPort >> 16) & 0xFF);
        buf6[2] = (byte) ((scanPort >> 8) & 0xFF);
        buf6[3] = (byte) (scanPort & 0xFF);

        byte[] buf7 = new byte[data.length()];
        buf7=data.getBytes();

        byte[] buf = new byte[16 +SrcIp.length()+DestIp.length()+data.length()];

        System.arraycopy(buf1, 0, buf, 0, 4);
        System.arraycopy(buf2, 0, buf, 4, 4);
        System.arraycopy(buf3, 0, buf, 8, 4);
        System.arraycopy(buf4, 0, buf, 12, SrcIp.length());
        System.arraycopy(buf5, 0, buf, 12+SrcIp.length(),DestIp.length() );
        System.arraycopy(buf6, 0, buf, 12+SrcIp.length()+DestIp.length(),4 );
        System.arraycopy(buf7, 0, buf, 16+SrcIp.length()+DestIp.length(),data.length());
        return  buf;
    }

    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }
    //byte 数组与 int 的相互转换
    public static int byteArrayToInt(byte[] b) {
        return b[3] & 0xFF |
                (b[2] & 0xFF) << 8 |
                (b[1] & 0xFF) << 16 |
                (b[0] & 0xFF) << 24;
    }

    public HashMap<Integer, Callback> getCallbackHashMap() {
        return callbackHashMap;
    }
}

3、定义传输的消息格式

package eco.data.m3.supernode.udp;

import java.io.IOException;
import java.lang.String;
import eco.data.m3.net.util.StreamUtil;
import io.netty.buffer.ByteBuf;

public class Udp_Message_Test {
    private int convId;
    private int SrcPort;
    private int DesPort;
    private String SrcIp;
    private String DestIp;
    private String content;
    public Udp_Message_Test( int convId,int SrcPort,int DesPort,String SrcIp,String DestIp,String content){
        this.convId=convId;
        this.SrcPort=SrcPort;
        this.DesPort=DesPort;
        this.SrcIp=SrcIp;
        this.DestIp=DestIp;
        this.content = content;
    }

    public void toByteBuf(ByteBuf out) throws IOException {

        out.writeInt(this.convId);
        out.writeInt(this.SrcPort);
        out.writeInt(this.DesPort);
        StreamUtil.toStream(this.SrcIp, out);
        StreamUtil.toStream(this.DestIp, out);
        StreamUtil.toStream(this.content, out);
    }

    public void fromByteBuf(ByteBuf in) throws IOException {
        this.convId = in.readInt();
        this.SrcPort = in.readInt();
        this.DesPort = in.readInt();
        this.SrcIp = StreamUtil.stringFromStream(in);
        this.DestIp = StreamUtil.stringFromStream(in);
        this.content = StreamUtil.stringFromStream(in);
    }

    public int getconvId() {
        return convId;
    }

    public void  setconvId(int convId ) {
        this.convId = convId ;
    }

    public int getSrcPort() {
        return SrcPort;
    }

    public void  setSrcPort(int SrcPort) {
        this.SrcPort =SrcPort ;
    }

    public int getDesPort() {
        return DesPort;
    }

    public void  setDesPort(int DesPort) {
        this.DesPort =DesPort ;
    }

    public String getSrcIp() {
        return SrcIp;
    }

    public void  setSrcIp(String SrcIp) {
        this.SrcIp =SrcIp ;
    }

    public String getDestIp() {
        return DestIp;
    }

    public void  setDestIp(String DestIp) {
        this.DestIp =DestIp ;
    }


    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}

4.定义测试类

package eco.data.m3.supernode.udp;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Random;

/**
 * Created by Lovell on 9/29/16.
 */

public class Test {
    private static Logger logger = LoggerFactory.getLogger(Test.class);

    @org.junit.Test
    public void test1() throws Exception {
//        Server.initServer();
        Client client2 = new Client(8698);
        int convId = new Random().nextInt();
        client2.sendPackage(convId,"hello",8698,8699,"10.108.78.53",
                "10.108.78.53", 8698,new Callback() {
                    @Override
                    public void onMessage(String content) {
                        //
                        success = true;
                        System.out.println("收到回调结果");

                    }

                    @Override
                    public void onFault(String reason) {

                    }
                });
    }

    boolean success = false;

    @org.junit.Test
    public void test2() throws Exception {
        Client client = new Client(8699);//client的监听端口
        int convId = new Random().nextInt();
        client.sendPackage(convId,"hello",8699,8698,"127.0.0.1",
                "127.0.0.1", 8699,new Callback() {
            @Override
            public void onMessage(String content) {
                //
                success = true;
                System.out.println("收到回调结果");

            }

            @Override
            public void onFault(String reason) {
            }
        });
//        client2.sendPackage("hello",8690,8691,"10.108.78.53",
//                "12.7.0.0.1", 8698,new Callback() {
//            @Override
//            public void onMessage(String content) {
//
//                //
//                success = true;
//
//
//            }
//
//            @Override
//            public void onFault(String reason) {
//
//            }
//        });
//        client.sendPackage("hello", new Callback() {
//            @Override
//            public void onMessage(String content) {
//                //
//                success = true;
//
//
//            }
//
//            @Override
//            public void onFault(String reason) {
//
//            }
//        });
//        client.sendPackage("hello", new Callback() {
//            @Override
//            public void onMessage(String content) {
//                //
//                success = true;
//
//
//            }
//
//            @Override
//            public void onFault(String reason) {
//
//            }
//        });
//        client.sendPackage("hello", new Callback() {
//            @Override
//            public void onMessage(String content) {
//                //
//                success = true;
//
//
//            }
//
//            @Override
//            public void onFault(String reason) {
//
//            }
//        });

        long untilTime = System.currentTimeMillis() + 10000;
        while (System.currentTimeMillis()<untilTime){
            Thread.sleep(10);
            if(success==true){
                System.out.println("回调完成");
                break;
            }
        }

        Thread.sleep(100000);
    }
}

Test类每定义一个client对象,调用sendPackage方法,就建立一个回调,随机生成一个整型数字convid,以<convid,callback>的形式存入哈希表中。在这里的测试中,本机给本机发送消息,触发client里的channelread0()方法,获取数据帧中的convid,判断哈希表中是否有对应的callback。如有,就调用onMessage方法回调回去。(也可以给其他节点发,但是要回复消息给本节点)

最后,放一个测试结果。在这里插入图片描述
参考文章:https://blog.csdn.net/xiaanming/article/details/8703708/
http://www.voidcn.com/article/p-zsnrikrg-mm.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【资源说明】 1、基于netty+websocket+springboot的实时聊天系统项目源码.zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 4、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip 基于netty+websocket+springboot的实时聊天系统项目源码.zip

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值