netty 3.9.2 UDP協議伺服器和用戶端DEMO

來源:互聯網
上載者:User

標籤:style   blog   java   color   使用   os   

說明:基於netty 3.9.2的udp協議實現的(如果你使用的版本是4.X或5.X,請參考其他方法);程式的邏輯結構是,用戶端發送給服務端一串資料,伺服器端返回給用戶端“A”。在進行遊戲開發時需要對udp的丟包進行處理,可以利用伺服器端的傳回值進行相關處理,以確定是否重發,這方面具體沒有實現。

文章結構:

一、伺服器端

1、UDPServer

2、UdpChannelPipelineFactory

3、UDPServerHandler

二、用戶端

1、UDPClient

2、UDPClientChannelPipelineFactory

3、UDPClientHandler

三、ScanGetPort擷取一個可用的連接埠號碼

一、伺服器端

1、UDPServer

初始化一個ConnectionlessBootstrap,setPipelineFactory,綁定一個連接埠號碼。ScanGetPort是一個工具類就是,擷取一個可用的連接埠號碼,原始碼在最後面貼出。

package com.ls.udp.server;import java.net.InetSocketAddress;import java.util.concurrent.Executors;import org.jboss.netty.bootstrap.ConnectionlessBootstrap;import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory;import com.andy.server.util.ScanGetPort;public class UDPServer {        public final int PORT;    public UDPServer(int port){        PORT=port;    }    private ConnectionlessBootstrap  bootstrap;    void start(){        //init the bootstrap        bootstrap=new ConnectionlessBootstrap(new NioDatagramChannelFactory(Executors.newCachedThreadPool()));        bootstrap.setPipelineFactory(new UdpChannelPipelineFactory());        bootstrap.bind(new InetSocketAddress(PORT));        System.out.println("server start at:"+":"+PORT);    }        public static void main(String[] args) {        /*         * 擷取一個可用的連接埠號碼         */        int port= new ScanGetPort().getPot(8080);        new UDPServer(port).start();    }    }

2、UdpChannelPipelineFactory

註冊一個handler

package com.ls.udp.server;import org.jboss.netty.channel.ChannelPipeline;import org.jboss.netty.channel.ChannelPipelineFactory;import org.jboss.netty.channel.Channels;public class UdpChannelPipelineFactory implements ChannelPipelineFactory{        /**     * set the channel pipeline     *      */    @Override    public ChannelPipeline getPipeline() throws Exception {        ChannelPipeline pipeline = Channels.pipeline();        pipeline.addLast("handler", new UDPServerHandler());        return pipeline;    }}

3、UDPServerHandler

handler類

package com.ls.udp.server;import org.jboss.netty.buffer.ChannelBuffer;import org.jboss.netty.buffer.DynamicChannelBuffer;import org.jboss.netty.channel.ChannelHandlerContext;import org.jboss.netty.channel.ExceptionEvent;import org.jboss.netty.channel.MessageEvent;import org.jboss.netty.channel.SimpleChannelUpstreamHandler;public class UDPServerHandler extends SimpleChannelUpstreamHandler{    /**     *  對於ChannelHandler,     *  是UDP與TCP區別的核心所在。     *  大家都知道UDP是不需連線的,     *  也就是說你通過 MessageEvent 參數對象的 getChannel() 方法擷取當前會話串連,     *  但是其 isConnected() 永遠都返回 false。     *  UDP 開發中在訊息擷取事件回調方法中,     *  擷取了當前會話串連 channel 對象後可直接通過 channel 的 write 方法發送資料給對端 channel.write(message, remoteAddress),     *  第一個參數仍然是要發送的訊息對象,      *  第二個參數則是要發送的對端 SocketAddress 地址對象。     *  這裡最需要注意的一點是SocketAddress,在TCP通訊中我們可以通過channel.getRemoteAddress()獲得,     *  但在UDP通訊中,我們必須從MessageEvent中通過調用getRemoteAddress()方法獲得對端的SocketAddress 地址。      */    @Override    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)            throws Exception {                ChannelBuffer buffer = (ChannelBuffer)e.getMessage();        byte[] recByte=buffer.copy().toByteBuffer().array();                String msg=new String(recByte);        System.out.println("from client:"+msg);                ChannelBuffer responseBuffer= new DynamicChannelBuffer(1);                responseBuffer.writeBytes("A".getBytes());                //write to the client        e.getChannel().write(responseBuffer, e.getRemoteAddress());                        super.messageReceived(ctx, e);    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)            throws Exception {        super.exceptionCaught(ctx, e);    }}

二、用戶端

(基本結構和伺服器端很像,不再贅述)

1、UDPClient

package com.ls.udp.client;import java.net.InetSocketAddress;import java.util.Scanner;import org.jboss.netty.bootstrap.ConnectionlessBootstrap;import org.jboss.netty.buffer.ChannelBuffer;import org.jboss.netty.buffer.DynamicChannelBuffer;import org.jboss.netty.channel.Channel;import org.jboss.netty.channel.socket.nio.NioDatagramChannelFactory;public class UDPClient {    private ConnectionlessBootstrap  bootstrap;    private Channel channel;    public void start(){        //init the bootstrap        bootstrap=new ConnectionlessBootstrap(new NioDatagramChannelFactory());        bootstrap.setPipelineFactory(new UDPClientChannelPipelineFactory());        bootstrap.setOption("localAddress", new InetSocketAddress(10001));        channel=bootstrap.bind();    }        public void writebytes(byte[] bt,InetSocketAddress isa){        if(bootstrap==null){            this.start();        }        ChannelBuffer responseBuffer= new DynamicChannelBuffer(12);                responseBuffer.writeBytes(bt);        channel.write(responseBuffer, isa);    }            public static void main(String[] args) {                        UDPClient uClient=new UDPClient();                        Scanner scanner=new Scanner(System.in);        String lienString=scanner.nextLine();        while(!lienString.equals("bye")){                        uClient.writebytes(lienString.getBytes(), new InetSocketAddress("192.168.1.107",8080));            lienString=scanner.nextLine();        }    }        }

 

 

 

2、UDPClientChannelPipelineFactory

 

package com.ls.udp.client;import org.jboss.netty.channel.ChannelPipeline;import org.jboss.netty.channel.ChannelPipelineFactory;import org.jboss.netty.channel.Channels;public class UDPClientChannelPipelineFactory implements ChannelPipelineFactory{        /**     * set the channel pipeline     *      */    @Override    public ChannelPipeline getPipeline() throws Exception {        ChannelPipeline pipeline = Channels.pipeline();        pipeline.addLast("handler", new UDPClientHandler());        return pipeline;    }}

 

 

3、UDPClientHandler

 

package com.ls.udp.client;import org.jboss.netty.buffer.ChannelBuffer;import org.jboss.netty.channel.ChannelHandlerContext;import org.jboss.netty.channel.ExceptionEvent;import org.jboss.netty.channel.MessageEvent;import org.jboss.netty.channel.SimpleChannelUpstreamHandler;public class UDPClientHandler extends SimpleChannelUpstreamHandler{    @Override    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)            throws Exception {                        ChannelBuffer buffer = (ChannelBuffer)e.getMessage();        byte[] recByte=buffer.copy().toByteBuffer().array();                String msg=new String(recByte);        System.out.println("from server:"+msg);                        super.messageReceived(ctx, e);    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)            throws Exception {        super.exceptionCaught(ctx, e);    }    }

三、ScanGetPort擷取一個可用的連接埠號碼

package com.andy.server.util;import java.io.IOException;import java.net.ServerSocket;/** * get the port * @author red * */public class ScanGetPort {    public synchronized  int  getPot(int first){        for(int i=first;i<65535;++i){            ServerSocket ss=null;            try {                 ss= new ServerSocket(i);            } catch (IOException e) {                //e.printStackTrace();            }finally{                if(ss!=null){                    if(ss.isBound()){                        try {                            ss.close();                            System.out.println(i);                            return i;                        } catch (IOException e) {                            e.printStackTrace();                        }                                            }                }            }        }        return -1;    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.