nio udp

扫码查看

程序是通了,但是没法转发,获取不到对方ip。nio中 udp使用的是DatagramChannel ,但是SelectorKey.channel()转化之后的DatagramChannel,调用getRemoteAddress()获取不到对方的ip信息。

看了下java doc

更多信息点这里

这个意思差不多就是DatagramChannel 是面向数据报的,是无连接的,所以不需要知道对面ip。然后就为null了。

但是

在bio中,通过DatagramPacket 是可以获取到对方ip信息的。 所以 ip信息应该是在报文里了。所以我要怎么样才能从报文中拿到这个ip呢?
假如使用nio,默认必须要通过ByteBuf 去读取,这样子就获取不到完整的报文信息了。我服了!
以下是代码

public class Server {
    private static LinkedList<SocketAddress> list=new LinkedList<SocketAddress>();
    private static final ExecutorService executorService = Executors.newFixedThreadPool(4);
    private static DatagramChannel server=null;
    private static Selector selector=null;
    static {
        try{
        server=DatagramChannel.open().bind(new InetSocketAddress(8889));
        server.configureBlocking(false);
        selector=Selector.open();

        }catch (Exception e){
            e.printStackTrace();
        }
    }
    public static void main(String[] args)throws Exception {

        server.register(selector, SelectionKey.OP_READ);
        while (true){
            if (selector.select()>0){
            Set<SelectionKey> keys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = keys.iterator();
            while (iterator.hasNext()){
                SelectionKey selectionKey = iterator.next();
                if (selectionKey.isReadable()){
                    saveIP(selectionKey);
                    String msg = readMsg(selectionKey);
                    broadcast(msg);
                }
                iterator.remove();
            }}
        }
    }
    public static void saveIP(SelectionKey selectionKey)throws Exception{
        if (selectionKey.channel() instanceof DatagramChannel){
            System.out.println(true);
        }
        DatagramChannel channel=(DatagramChannel)selectionKey.channel();
        SocketAddress address = channel.getRemoteAddress();
        if (!list.contains(address)){
            list.add(address);
            System.out.println("新增ip:"+address);
        }
        System.out.println("当前udp 保存的ip数量:"+list.size());
    }
    public static void broadcast(String msg) throws Exception{
        ByteBuffer byteBuffer=ByteBuffer.wrap(msg.getBytes());
        //DatagramPacket packet=new DatagramPacket(msg.getBytes(),0,msg.getBytes().length);
        for (SocketAddress address:list
             ) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    try{
                    server.send(byteBuffer,address);
                    }catch (Exception e){
                        System.out.println(Thread.currentThread().getName()+":"+address+"发送失败");
                    }
                }
            });
        }
    }
    public static String readMsg(SelectionKey selectionKey)throws Exception{
        DatagramChannel channel=(DatagramChannel)selectionKey.channel();
        ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
        channel.receive(byteBuffer);
        byteBuffer.flip();
        String msg=new String(byteBuffer.array(),"utf-8");
        System.out.println("收到消息:"+msg);
        return msg;
    }
}
12-30 17:54
查看更多