DatagramChannel 举例

Server 端:

package datagram;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.charset.Charset;

public class UDPServer {

    private int port = 8008;
    private DatagramChannel channel;
    private int MAX_SIZE = 1024;

    public UDPServer(int port, int size) throws IOException {

        this.port = port;
        this.MAX_SIZE = size;

        channel = DatagramChannel.open();
        SocketAddress localAddr = new InetSocketAddress(this.port);
        channel.bind(localAddr);
        System.out.println("Server Starting...");

    }

    public UDPServer() throws IOException {

        this(8008, 1024);
    }

    public String echo(String msg) {

        return "echo:" + msg;
    }

    public void service() {

        ByteBuffer receiveBuffer = ByteBuffer.allocate(MAX_SIZE);
        while(true) {
            try {
                receiveBuffer.clear();
                InetSocketAddress client = (InetSocketAddress) channel.receive(receiveBuffer);
                receiveBuffer.flip();
                String msg = Charset.forName("GBK").decode(receiveBuffer).toString();
                System.out.println(client.getAddress().getHostAddress() + ":" + client.getPort() + " > " + msg);

                channel.send(ByteBuffer.wrap(echo(msg).getBytes()), client);

                if(msg.startsWith("bye"))
                    break;

            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

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

        new UDPServer().service();
    }
}

Client 端:

package datagram;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Set;

public class UDPClient {

    private DatagramChannel datagramChannel = null;
    private ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
    private ByteBuffer receiveBuffer = ByteBuffer.allocate(1024);
    private Charset charset = Charset.forName("GBK");
    private Selector selector;

    public UDPClient(int port) throws IOException {

        datagramChannel = DatagramChannel.open();
        InetAddress ia = InetAddress.getByName("10.11.3.220");
        InetSocketAddress isa = new InetSocketAddress(ia, port);
        datagramChannel.configureBlocking(false);
        datagramChannel.bind(isa);

        ia = InetAddress.getByName("10.11.3.160");
        isa = new InetSocketAddress(ia, 8008);
        datagramChannel.connect(isa);
        selector = Selector.open();
    }

    public UDPClient() throws IOException {

        this(7000);
    }

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

        int port = 7000;
        if(args.length > 0)
            port = Integer.parseInt(args[0]);

        final UDPClient client = new UDPClient(port);
        Thread receiver = new Thread() {
            public void run() {
                client.receiveFromUser();
            }
        };

        receiver.start();
        client.talk();
    }

    public void receiveFromUser() {

        try {
            BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));
            String msg = null;
            while((msg = localReader.readLine()) != null) {
                synchronized(sendBuffer) {
                    sendBuffer.put(encode(msg + "\r\n"));
                }
                if(msg.equals("bye"))
                    break;
             }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void talk() throws IOException {

        datagramChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
        while(selector.select() > 0) {
            Set<SelectionKey> readyKeys = selector.selectedKeys();
            Iterator<SelectionKey> it = readyKeys.iterator();
            while(it.hasNext()) {
                SelectionKey key = null;
                try {
                    key = it.next();
                    it.remove();

                    if(key.isReadable()) {
                        receive(key);
                    }

                    if(key.isWritable()) {
                        send(key);
                    }
                }
                catch (IOException e) {
                    e.printStackTrace();
                    try {
                        if(key != null) {
                            key.cancel();
                            key.channel().close();
                        }
                    }
                    catch(Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    }

    public void send(SelectionKey key) throws IOException {

        DatagramChannel datagramChannel = (DatagramChannel) key.channel();
        synchronized(sendBuffer) {
            sendBuffer.flip();
            datagramChannel.write(sendBuffer);
            sendBuffer.compact();
        }
    }

    public void receive(SelectionKey key) throws IOException {

        DatagramChannel datagramChannel = (DatagramChannel) key.channel();
        datagramChannel.read(receiveBuffer);
        receiveBuffer.flip();

        String receiveData = decode(receiveBuffer);
        if(receiveData.indexOf("\n") == -1)
            return;

        String outputData = receiveData.substring(0, receiveData.indexOf("\n")+1);
        System.out.println(outputData);

        if(outputData.equals("echo:bye\r\n")) {
            key.cancel();
            datagramChannel.close();
            System.out.println("Closed connection with Server");
            selector.close();
            System.exit(0);
        }

        ByteBuffer temp = encode(outputData);
        receiveBuffer.position(temp.limit());
        receiveBuffer.compact();
    }

    public String decode(ByteBuffer buffer) {

        CharBuffer charBuffer = charset.decode(buffer);
        return charBuffer.toString();
    }

    public ByteBuffer encode(String str) {

        return charset.encode(str);
    }
}
时间: 2024-08-01 23:41:57

DatagramChannel 举例的相关文章

Java-NIO(八):DatagramChannel

Java NIO中的DatagramChannel是一个能收发UDP包的通道.操作步骤: 1)打开 DatagramChannel 2)接收/发送数据 同样它也支持NIO的非阻塞模式操作,例如: 1 @Test 2 public void send() throws IOException { 3 DatagramChannel channel = DatagramChannel.open(); 4 channel.configureBlocking(false); 5 6 ByteBuffer

JavaSE-接口应用举例

package com.btp.t2; /* * 接口应用的举例 */ public class TestUSB { public static void main(String[] args) { new Computer().doWork(new Printer()); new Computer().doWork(new Flash()); //实现接口的匿名类的对象 USB phone=new USB(){ @Override public void start() { // TODO 自

veridata实验举例(3)验证veridata查找出insert操作导致的不同步现象

veridata实验举例(3)验证veridata查找出insert操作导致的不同步现象 续接:<veridata实验举例(2)验证表BONUS与表SALGRADE两节点同步情况>,地址:点击打开链接 环境: Item Source System Target System Platform Red Hat Enterprise Linux Server release 5.4 Red Hat Enterprise Linux Server release 5.4 Hostname gc1 g

C++多重继承中的虚继承和虚函数举例

上一篇虚继承举例:http://10638473.blog.51cto.com/10628473/1964414 本文将A类中的show()函数前加上virtual关键字. //多重继承 #include <iostream> using namespace std; class A { public:     int a;     A(int a=0):a(a)     {         cout<<"A基类A::A()"<<endl;     

c++局部变量经典举例

局部变量: 在函数内部声明的变量为局部变量,局部变量的意思即该变量只存活在该函数中,假如该函数调用结束,那么该变量的寿命也结束了. 举例: #include<iostream> using namespace std; void swap(int ,int );//两个参数变量可以省略 int main() { int x=3,y=4; cout<<"在main函数中,调用swap函数之前,x的值为"<<x<<",y的值为:&q

cookie使用举例(添加购物车商品_移除购物车商品)

之前介绍过cookie和session的原理和区别.下面举例说明一下cookie在实际项目中的使用.使用cookie实现购物车功能: 1.往购物车添加商品 2.从购物车里移除商品 主要是要点是:以产品id作为主键进行判断.如果这个添加的产品id信息已经在cookie里面存在,则添加失败(这里不考虑同一个商品重复添加多个的问题.因为只是cookie的简单举例):否则则把该产品的信息保存在cookie里面.因此存在用户手动清楚cookie的情况,所以需要判断: 1 if(cookieMap.cont

聚集索引与非聚集索引的用法举例与使用注意

聚集索引 用法举例 小明需要查找一个人的姓名,知道他在公司的营销部门的1010办公室的4号座位.这个时候如果需要专门为小明建一个聚集索引表就是,以公司部门表内部门名称排序,再以房间总表序号排序,最后以房间详细表的座位表排序,这样就可以最快的找到他要找的人 聚集索引类似于一个字典,我们知道拼音来寻找字,首先我们知道字音节的首字母,从按a-z排序的字典中找到这个字首字母所在的区域,再从这个区域找到韵母所在的区域,当然韵母在字典中也有顺序,最后就可以找到我们想要的字了 注意事项 限制原则 每个表只能有

shell-script的简单举例

#!/bin/bash #defind the path PATH=/usr/local export PATH read -p "please input your first name:" firstname reap -p "please input your last name:" lastname echo -e "\nyour name is: $firstname $lastname" #use date create file r

对拍程序讲解及源码举例

对拍程序 一.介绍 在做题或者正式比赛过程中总会把水题做水做乱,但因为样例有坑所以直接过了样例,然后拿去评测结果发现全WA.那如何在这种情况下检查自己程序或算法的正确性呢?对拍是一个简便省事的方案. 所谓“对拍”,顾名思义,就是让两者相互比对.所谓“两者”,一是你要测试的程序,二是一个答案在该程序在一定范围(时间/空间)内结果必定正确的程序(一般是用暴力求解的程序). 两个程序准备好编译好了以后,就可以开始准备测试用的输入样例了.但是输入样例要是人为准备起来的话肯定浪费时间还费脑,更别提在正式比