Java NIO 学习--DataGramChannel

Posted 智公博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java NIO 学习--DataGramChannel相关的知识,希望对你有一定的参考价值。

本节讲解的是DataGramChannel,类似与java 网络编程的DatagramSocket类;使用UDP进行网络传输,UDP是无连接,面向数据包的协议,对传输的数据不保证安全与完整;

一、获取DataGramChannel

获取DataGramChannel通常是通过open静态方法得到:

DatagramChannel datagramChannel = DatagramChannel.open();

datagramChannel同样有非阻塞模式,可以通过方法configureBlocking设置:

datagramChannel.configureBlocking(true);

二、接收消息

获取到DataGramChannel后,接收消息,需要先做绑定地址操作:

datagramChannel.bind(new InetSocketAddress(1234));

然后通过receive方法接收消息,这个方法返回一个SocketAddress对象,表示发送消息方的地址:

SocketAddress socketAddress = datagramChannel.receive(buffer);

在非阻塞模式下,可能会立即返回null;

三、发送消息

由于UDP下,服务端和客户端通信并不需要建立连接,只需要知道对方地址即可发出消息,但是是否发送成功或者成功被接收到是没有保证的;发送消息通过send方法发出,改方法返回一个int值,表示成功发送的字节数:

int send = channel.send(buffer, new InetSocketAddress("localhost",1234));

在非阻塞模式下,可能会立即返回0;

四、完整实例

DataGramChannel的一般使用还是比较简单,下面通过一个发送、接收回应的代码实例说明:

服务端:接收客户端发送消息,收取到消息后,给发送方一个回应

public class DataDramdChannelReceiveTest 

    public static void main(String[] args) throws IOException 

        DatagramChannel datagramChannel = DatagramChannel.open();
        datagramChannel.bind(new InetSocketAddress(1234));

        ByteBuffer buffer = ByteBuffer.allocate(1024);
        byte b[];
        while(true) 
            buffer.clear();
            SocketAddress socketAddress = datagramChannel.receive(buffer);
            if (socketAddress != null) 
                int position = buffer.position();
                b = new byte[position];
                buffer.flip();
                for(int i=0; i<position; ++i) 
                    b[i] = buffer.get();
                
                System.out.println("receive remote " +  socketAddress.toString() + ":"  + new String(b, "UTF-8"));
                //接收到消息后给发送方回应
                sendReback(socketAddress,datagramChannel);
            
        
    

    public static void sendReback(SocketAddress socketAddress,DatagramChannel datagramChannel) throws IOException 
        String message = "I has receive your message";
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        buffer.put(message.getBytes("UTF-8"));
        buffer.flip();
        datagramChannel.send(buffer, socketAddress);
    

客户端:发送控制台输入的内容并接收服务端回应

public class DataGramdChannelSendTest 

    public static void main(String[] args) throws IOException 

        final DatagramChannel channel = DatagramChannel.open();
        //接收消息线程
        new Thread(new Runnable() 
            @Override
            public void run() 
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                byte b[];
                while(true) 
                    buffer.clear();
                    SocketAddress socketAddress = null;
                    try 
                        socketAddress = channel.receive(buffer);
                     catch (IOException e) 
                        e.printStackTrace();
                    
                    if (socketAddress != null) 
                        int position = buffer.position();
                        b = new byte[position];
                        buffer.flip();
                        for(int i=0; i<position; ++i) 
                            b[i] = buffer.get();
                        
                        try 
                            System.out.println("receive remote " +  socketAddress.toString() + ":"  + new String(b, "UTF-8"));
                         catch (UnsupportedEncodingException e) 
                            e.printStackTrace();
                        
                    
                
            
        ).start();;

        //发送控制台输入消息
        while (true) 
            Scanner sc = new Scanner(System.in);
            String next = sc.next();
            try 
                sendMessage(channel, next);
             catch (IOException e) 
                e.printStackTrace();
            
        
    

    public static void sendMessage(DatagramChannel channel, String mes) throws IOException 
        if (mes == null || mes.isEmpty()) 
            return;
        
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        buffer.clear();
        buffer.put(mes.getBytes("UTF-8"));
        buffer.flip();
        System.out.println("send msg:" + mes);
        int send = channel.send(buffer, new InetSocketAddress("localhost",1234));
    

以上是关于Java NIO 学习--DataGramChannel的主要内容,如果未能解决你的问题,请参考以下文章

java : nio 学习

Java NIO学习

NIO学习总结

Java NIO学习一

java nio 学习

Java NIO