客户端 UDP 调用netty 参考



import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
import org.jboss.netty.channel.socket.DatagramChannel;
import org.jboss.netty.channel.socket.DatagramChannelFactory;
import org.jboss.netty.channel.socket.oio.OioDatagramChannelFactory;
import org.jboss.netty.util.AlarmManagerTimer;
import org.jboss.netty.util.AlarmManagerTimerFactory;

import com.lenovo.lsf.push.log.PushLog;
import com.lenovo.lsf.push.log.PushLog.LEVEL;
import com.lenovo.lsf.push.net.handler.PushUDPHandler;
import com.lenovo.lsf.push.net.pipeline.PushUDPPipelineFactory;
import com.lenovo.lsf.push.net.protobuf.PushUDPCommandProtos.COMMAND_TYPE;
import com.lenovo.lsf.push.net.protobuf.PushUDPCommandProtos.PUSH_UDP_COMMAND;
import com.lenovo.lsf.push.net.protobuf.PushUDPCommandProtos.PUSH_UDP_COMMAND.TTL_INIT;
import com.lenovo.lsf.push.net.protobuf.PushUDPCommandProtos.PUSH_UDP_COMMAND.TTL_INIT.Builder;
import com.lenovo.lsf.push.util.DeviceUtil;
import com.lenovo.lsf.push.util.PushWakeLock;
import com.lenovo.lsf.sdac.SDACDeviceInfo;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class PushMessageUDPImpl extends PushDAONetAware implements IPushMessage {

    private Context context;
    private static ConnectionlessBootstrap bootstrap;
    private  ChannelFuture channelFuture;
    private static DatagramChannel databramChannel;
    private String lastNetType="";
    private String lastIPAddress="";
    private String HOST;
    private int PORT;
    private String requestURI;
    public static final String PUSH_UDP_WAKE_LOCK = "PUSH_UDP_WAKE_LOCK";
    public static final int INIT_UDP_FAIL_COUNT = 0;
    private int udpFailCount = INIT_UDP_FAIL_COUNT;

    public static final int MAX_UDP_INIT_COUNT = 5;
    public static String last_local_ip = null;
    public static int ttl = 25;
    private PushMessageUDPDelayRetryProxy delayProxy;
    private PushUDPIntervalTunningManager tunningManager;
    private AlarmManagerTimerFactory timerFactory;
    //用来生成唯一的PushUDPCommand id
    private static AtomicInteger requstCode = new AtomicInteger(0);
    //id max
    private final int MAX_TIMER = 256;
    private boolean isTTLInitRunning = false;
    private boolean udpInitialized = false;
    

    public PushMessageUDPImpl(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        this.context = context;
        delayProxy = new PushMessageUDPDelayRetryProxy();
        tunningManager = new PushUDPIntervalTunningManager();
        timerFactory = new AlarmManagerTimerFactory(PushService.ACTION_INTERNAL_UDP_ALARM_TIMER);

    }
    
    public int getUdpFailCount() {
        return udpFailCount;
    }

    public void setUdpFailCount(int udpFailCount) {
        this.udpFailCount = udpFailCount;
    }


    @Override
    public void resetDayPollCount() {
        // TODO Auto-generated method stub

    }

    @Override
    public void resetFailCount() {
        // TODO Auto-generated method stub
        udpFailCount = INIT_UDP_FAIL_COUNT;
    }
    


    @Override
    public void online() {
        // TODO Auto-generated method stub
        start();
    }

    @Override
    public void offline() {
        // TODO Auto-generated method stub
        stop();
    }

    public boolean isTTLInitRunning() {
        return isTTLInitRunning;
    }

    public void setTTLInitRunning(boolean isTTLInitRunning) {
        this.isTTLInitRunning = isTTLInitRunning;
    }
    
    @Override
    public void start() {
        // TODO Auto-generated method stub
        if(isSwitchOn() && isNetAvailable() && !isEmpty()){

            String currentNetType = getNetType();
            String currentIPAddress = getIpAddress();
                
            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.start", "lastNetType:"+lastNetType+", currentNetType:"+currentNetType);    
            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.start", "lastIPAddress:"+lastIPAddress+", currentIPAddress:"+currentIPAddress);    
            
            lastNetType = currentNetType;
            lastIPAddress = currentIPAddress;
            
            requestURI = getPushUDPRequestUrl();
            
            if(requestURI != null && requestURI.indexOf(":") != -1) {
                HOST = requestURI.substring(0, requestURI.indexOf(":"));
                String portStr = requestURI.substring(requestURI.indexOf(":") + 1, requestURI.length());
                try{
                    PORT = Integer.parseInt(portStr);
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }
                PushLog.log(context, PushLog.LEVEL.INFO, "PushMessageUDPImpl.start",
                        "HOST:" + HOST+"PORT:"+PORT);
            }
            



            /*
            if (currentIPAddress != null
                    && !currentIPAddress.equals(lastIPAddress)) {

                initTTL();

            }
            */
            if(!isTTLInitRunning()) {
                initTTL();
            }
                
        }else{
            Intent i = PushService.newIntent(context,PushService.ACTION_INTERNAL_UDP_STOP_ALL);
            //context.sendBroadcast(i);
            i = PushIntentAware.awareIntent(context, i);
            context.startService(i);
        }
    }
    
    void initTTL() {
        setTTLInitRunning(true);
        

        setUdpInitialized(false);
        
        PushWakeLock.acquire(context, PUSH_UDP_WAKE_LOCK, 30);
        DatagramChannelFactory f = new OioDatagramChannelFactory(
                Executors.newCachedThreadPool());
        bootstrap = new ConnectionlessBootstrap(f);

        // Configure the pipeline factory.
        bootstrap.setPipelineFactory(new PushUDPPipelineFactory(
                context,timerFactory.getNewAlarmManagerTimer(context), this));

        // Enable broadcast
        bootstrap.setOption("broadcast", "false");
        bootstrap.setOption("receiveBufferSizePredictorFactory",
                new FixedReceiveBufferSizePredictorFactory(102400));

        databramChannel = (DatagramChannel) bootstrap
                .bind(new InetSocketAddress(0));
        
        write();
    }
    
    void write() {       
        // write TTL_INIT to server
        PUSH_UDP_COMMAND command = getInitTTLCommand(getUDPPushCommandId());
        PushLog.log(context, PushLog.LEVEL.INFO,
                "PushMessageUDPImpl.write", "send ttl init to server>>>>>>>>>>>>ttlInit:"+command.getTtlInit().getTtl());
        channelFuture = databramChannel.write(command,
                new InetSocketAddress(HOST,PORT));
        
        
        channelFuture.addListener(new ChannelFutureListener(){

            @Override
            public void operationComplete(ChannelFuture future)
                    throws Exception {
                // TODO Auto-generated method stub
                if (!future.isSuccess()) {
                    timerFactory.destroyAlarmManagerTimer(context);
                    setTTLInitRunning(false);
                    if(future != null){
                        Channel channel = future.getChannel();
                        if(channel != null){
                            channel.close();
                            // Wait for the server to close the connection.
                            channel.getCloseFuture().awaitUninterruptibly();
                        }
                    }

                    PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.sendTTLInitRequest", "connect fail begin to release wake lock!!!");
                    PushWakeLock.release(context,PUSH_UDP_WAKE_LOCK);
               
                }
            }
            
        });
}
    
    public PUSH_UDP_COMMAND getInitTTLCommand(int id){
        // build TTL_INIT command
        Builder builder = TTL_INIT.newBuilder();
        String st = getSt();
        builder.setSt(st==null ? "":st);
        builder.setTtl(ttl);
        try{
            String netType = DeviceUtil.getNetType(context);
            if(netType != null && !netType.equals("")) {
                if(netType.equals("wifi"))
                    builder.setNetType(DeviceUtil.WIFI);
                else if(netType.equals("mobile"))
                    builder.setNetType(DeviceUtil.MOBILE);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        try{
            String optCode = SDACDeviceInfo.getInstance().getSdacInfo(context)
                    .getSystemID();
            if(optCode != null && !optCode.equals("")) {
                int code = Integer.parseInt(optCode);
                builder.setOptCode(code);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        try{
            String cellId = DeviceUtil.getCellId(context);
            if(cellId != null && !cellId.equals("")) {
                int cId = Integer.parseInt(cellId);
                builder.setNetType(cId);
            }
            
        } catch (Exception e){
            e.printStackTrace();
        }
        
        TTL_INIT ttlInit = builder.build();
        PUSH_UDP_COMMAND command = PUSH_UDP_COMMAND.newBuilder().setId(id)
                .setType(COMMAND_TYPE.TTL_INIT).setVer(PushUDPHandler.COMMAND_VERSION).setTtlInit(ttlInit).build();
        return command;
    }
    
    @Override
    public void stop() {
        // TODO Auto-generated method stub
        if(isTTLInitRunning()) {
            delayProxy.cancelUDPPushRetryAlarm(context);
            
            setTTLInitRunning(false);
            resetFailCount();
            PushLog.log(context, PushLog.LEVEL.INFO, "PushMessageUDPImpl.stop",
                    "PushMessageUDPImpl.stop");
            timerFactory.destroyAlarmManagerTimer(context);
            if(channelFuture != null){
                Channel channel = channelFuture.getChannel();
                if(channel != null){
                    PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.stop", "channel has been closed by future !!!");
                    channel.close();
                    // Wait for the server to close the connection.
                    channel.getCloseFuture().awaitUninterruptibly();
                }
            }
            
        }
    }

    @Override
    public void udpAvaliable() {
        // TODO Auto-generated method stub

    }

    @Override
    public void udpUnAvaliable() {
        // TODO Auto-generated method stub

    }

    @Override
    public void expire(int requestCode) {
        // TODO Auto-generated method stub
        AlarmManagerTimer timer  = timerFactory.getAlarmManagerTimer(context);
        
        // TODO Auto-generated method stub
        if(timer != null){
          timer.expire(requestCode);
        }else{
            
            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.expire()", "push service instance has been recreated, restart initTTL !!!");

            setTTLInitRunning(false);
            if(channelFuture != null){
            Channel channel = channelFuture.getChannel();
            if(channel != null){
            channel.close();
            // Wait for the server to close the connection.
            channel.getCloseFuture().awaitUninterruptibly();
            }
            }


            
            Intent i = PushService.newIntent(context,PushService.ACTION_INTERNAL_UDP_START_ALL);
            //context.sendBroadcast(i);
            i = PushIntentAware.awareIntent(context, i);
            context.startService(i);
        }
    }

    @Override
    public void switchOn() {
        // TODO Auto-generated method stub
        setSwitch(context, true);
    }

    @Override
    public void switchOff() {
        // TODO Auto-generated method stub
        setSwitch(context, false);
    }
    
    public AlarmManagerTimerFactory getTimerFactory() {
        return timerFactory;
    }

    public void setTimerFactory(AlarmManagerTimerFactory timerFactory) {
        this.timerFactory = timerFactory;
    }

    public PushMessageUDPDelayRetryProxy getDelayProxy() {
        return delayProxy;
    }

    public void setDelayProxy(PushMessageUDPDelayRetryProxy delayProxy) {
        this.delayProxy = delayProxy;
    }
    
    public PushUDPIntervalTunningManager getTunningManager() {
        return tunningManager;
    }

    public void setTunningManager(PushUDPIntervalTunningManager tunningManager) {
        this.tunningManager = tunningManager;
    }
    
    public boolean isUdpInitialized() {
        return udpInitialized;
    }

    public void setUdpInitialized(boolean udpInitialized) {
        this.udpInitialized = udpInitialized;
    }

    
    private String getPushUDPRequestUrl() {

        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<String> future = (Future<String>) executor
                .submit(new Callable<String>() {

                    @Override
                    public String call() throws Exception {
                        String addr = getServerAddr("rpsb002");
                        if(addr == null) {
                            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.getPushUDPRequestUrl", "get server address failed");
                        }else{
                            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.getPushUDPRequestUrl", "url:"+addr);
                        }
                        
                        StringBuilder sb = new StringBuilder(addr==null ? "":addr);

                        PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.getPushUDPRequestUrl", "command line is:" + sb.toString());
                        
                        return sb.toString();
                    }

                });

        try {
            String pushURI = future.get();
            return pushURI;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

    
    //生成全局唯一UDPPushCommand id
    public int getUDPPushCommandId() {
        int code = requstCode.getAndIncrement();
        if (code > MAX_TIMER) {
            code = 0;
            requstCode = new AtomicInteger(0);
        }
        return code;
    }

    @Override
    public void resetUdpAvaliable() {
        // TODO Auto-generated method stub
        
    }


}

### 回答1: Netty是一个基于Java的网络编程框架,它支持多种协议和传输方式,包括UDP。要创建一个NettyUDP客户端,需要以下步骤: 1. 创建一个Bootstrap对象,用于配置和启动Netty客户端。 2. 设置客户端的Channel类型为NioDatagramChannel,这是UDP协议的通道类型。 3. 设置客户端的处理器,用于处理接收到的消息和发送消息。 4. 连接到UDP服务器,可以使用Bootstrap的connect()方法或者bind()方法来指定服务器的地址和端口号。 5. 发送消息到服务器,可以使用客户端的Channel对象来发送数据。 下面是一个简单的Netty UDP客户端的示例代码: ``` EventLoopGroup group = new NioEventLoopGroup(); Bootstrap bootstrap = new Bootstrap(); bootstrap.group(group) .channel(NioDatagramChannel.class) .handler(new SimpleChannelInboundHandler<DatagramPacket>() { @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception { // 处理接收到的消息 } }); Channel channel = bootstrap.bind(0).sync().channel(); InetSocketAddress serverAddress = new InetSocketAddress("localhost", 12345); channel.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer("Hello", CharsetUtil.UTF_8), serverAddress)); ``` 在这个示例代码中,我们创建了一个NioEventLoopGroup对象作为事件循环组,创建了一个Bootstrap对象,并设置了客户端的通道类型为NioDatagramChannel,设置了客户端的处理器为一个SimpleChannelInboundHandler对象。然后,我们绑定了客户端的端口号为0,表示由系统自动分配一个未使用的端口号。最后,我们创建了一个InetSocketAddress对象,指定了服务器的地址和端口号,并使用客户端的Channel对象发送了一条消息到服务器。 ### 回答2: netty是一个高性能的网络编程框架,可以用于构建各种类型的网络应用程序,包括UDP(User Datagram Protocol)客户端。 在使用netty构建UDP客户端时,需要按照以下步骤进行操作。 首先,需要创建一个Bootstrap实例,用于配置和启动netty客户端。可以通过如下代码创建Bootstrap实例: ``` Bootstrap bootstrap = new Bootstrap(); ``` 接下来,需要配置Bootstrap实例。配置包括指定EventLoopGroup用于处理客户端的I/O操作,设置通道类型为NioDatagramChannel(用于UDP协议),设置远程服务器的地址和端口等。 ``` bootstrap.group(new NioEventLoopGroup()) .channel(NioDatagramChannel.class) .remoteAddress(new InetSocketAddress("服务器地址", 服务器端口)) .handler(new ChannelInitializer<DatagramChannel>() { @Override protected void initChannel(DatagramChannel channel) throws Exception { ChannelPipeline pipeline = channel.pipeline(); // 添加自定义的处理器 pipeline.addLast(new MyHandler()); } }); ``` 然后,需要自定义一个处理器类(MyHandler),用于处理接收和发送的数据。在该类中,可以重写channelRead方法用于处理接收到的数据,也可以重写channelActive方法用于在连接建立时发送数据。 ``` public class MyHandler extends SimpleChannelInboundHandler<DatagramPacket> { @Override protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception { ByteBuf buf = packet.content(); // 处理接收到的数据 } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { // 发送数据 ByteBuf buf = ctx.alloc().buffer(); // 将数据写入buf DatagramPacket packet = new DatagramPacket(buf, remoteAddress); ctx.writeAndFlush(packet); } } ``` 最后,调用bootstrap的bind方法启动客户端,并通过调用ChannelFuture的sync方法阻塞线程直到连接完成。 ``` ChannelFuture future = bootstrap.bind().sync(); ``` 以上就是使用netty构建UDP客户端的简单流程。通过创建Bootstrap实例、配置与远程服务器的连接、自定义处理器类以及启动客户端,就可以实现netty UDP客户端的功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FocusOneThread

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值