netty 5.xUDP組播

使用的Maven依賴

<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>5.0.0.Alpha2</version>
</dependency>

server端代碼

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.NetUtil;

public class MulticastSession {

	private final InetSocketAddress groupAddress;//加入的組播地址
	
	
	
	public static void main(String[] args) {
//		System.setProperty("java.net.preferIPv4Stack", "true");//只使用IPV4
		InetSocketAddress address = new InetSocketAddress("224.1.1.1", 9000);
		MulticastSession session = new MulticastSession(address);
		session.run();
	}
	

	public MulticastSession(InetSocketAddress groupAddress) {
		this.groupAddress = groupAddress;
	}

	public void run() {
		EventLoopGroup group = new NioEventLoopGroup();
		try {
			NetworkInterface ni = NetUtil.LOOPBACK_IF;
//			InetAddress localAddress = InetAddress.getByName("192.168.100.101");
			Enumeration<InetAddress> addresses = ni.getInetAddresses();
			InetAddress localAddress = null;
			while (addresses.hasMoreElements()) {
				InetAddress address = addresses.nextElement();
				if (address instanceof Inet4Address){
					localAddress = address;
				}
			}
			System.out.println(localAddress);
			Bootstrap b = new Bootstrap();
			b.group(group).channel(NioDatagramChannel.class)
			.localAddress(localAddress,groupAddress.getPort())
            .option(ChannelOption.IP_MULTICAST_IF, ni)//組播
            .option(ChannelOption.IP_MULTICAST_ADDR, localAddress)
//            .option(ChannelOption.IP_MULTICAST_LOOP_DISABLED, false)
            .option(ChannelOption.SO_REUSEADDR, true)//重複地址
//			.option(ChannelOption.SO_BROADCAST, false)//廣播
			.handler(new ChannelInitializer<NioDatagramChannel>() {
				@Override
				public void initChannel(NioDatagramChannel ch) throws Exception {
					ChannelPipeline addLast = ch.pipeline().addLast();
					addLast.addLast(new SimpleChannelInboundHandler<DatagramPacket>() {//接收信息處理
						@Override
						protected void messageReceived(ChannelHandlerContext ctx, DatagramPacket msg)
								throws Exception {
							System.out.println(msg.sender()+" >>> "+new String(buf.readBytes(buf.readableBytes()).array()));
						}
					});
				}
			});
			
			NioDatagramChannel ch = (NioDatagramChannel)b.bind(groupAddress.getPort()).sync().channel();
            ch.joinGroup(groupAddress, ni).sync();
            ch.closeFuture().await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			group.shutdownGracefully();//優雅退出
		}
	}
}

遇到的問題及處理

IPv6 socket cannot join IPv4 multicast group

java.lang.IllegalArgumentException: IPv6 socket cannot join IPv4 multicast group
at sun.nio.ch.DatagramChannelImpl.innerJoin(DatagramChannelImpl.java:808)
at sun.nio.ch.DatagramChannelImpl.join(DatagramChannelImpl.java:894)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:406)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:379)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:372)
at test.MulticastSession.run(MulticastSession.java:79)
at test.MulticastSession.main(MulticastSession.java:34)

在項目啓動時執行這段代碼禁用IPV6
System.setProperty("java.net.preferIPv4Stack", "true");

java.lang.NullPointerException: multicastAddress

java.lang.NullPointerException: multicastAddress
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:396)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:379)
at io.netty.channel.socket.nio.NioDatagramChannel.joinGroup(NioDatagramChannel.java:372)
at test.MulticastSession.run(MulticastSession.java:77)
at test.MulticastSession.main(MulticastSession.java:32)

使用 這種方式來創建 InetSocketAddress
new InetSocketAddress("224.1.1.1", 9000);
而不要使用下面的這種方式
InetSocketAddress.createUnresolved("224.1.1.1", 9000);

client端代碼

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.CharsetUtil;
import io.netty.util.NetUtil;

public class MulticastClient {
	
	private InetSocketAddress groupAddress;
	
	public MulticastClient(InetSocketAddress groupAddress) {
		this.groupAddress = groupAddress;
	}
	
	
	public void run() {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
//            NetworkInterface ni = NetworkInterface.getByName("en1");
            NetworkInterface ni = NetUtil.LOOPBACK_IF;
            Enumeration<InetAddress> addresses = ni.getInetAddresses();
            InetAddress localAddress = null;
            while (addresses.hasMoreElements()) {
                InetAddress address = addresses.nextElement();
                if (address instanceof Inet4Address){
                    localAddress = address;
                }
            }

            Bootstrap b = new Bootstrap();
			b.group(group).channel(NioDatagramChannel.class)
			.localAddress(localAddress,groupAddress.getPort())
            .option(ChannelOption.IP_MULTICAST_IF, ni)//組播
            .option(ChannelOption.SO_REUSEADDR, true)//重複地址
			.handler(new ChannelInitializer<NioDatagramChannel>() {

				@Override
				protected void initChannel(NioDatagramChannel ch) throws Exception {
					ch.pipeline().addLast(new SimpleChannelInboundHandler<DatagramPacket>() {

						@Override
						protected void messageReceived(ChannelHandlerContext ctx, DatagramPacket msg) throws Exception {
							System.out.println(msg);
						}
						
					});
				}
				
			});

            Channel ch = b.bind().sync().channel();
            ch.writeAndFlush(new DatagramPacket(
                    Unpooled.copiedBuffer("hello world", CharsetUtil.UTF_8),
                    groupAddress)).sync();//發送數據

            ch.close().awaitUninterruptibly();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            group.shutdownGracefully();
        }
    }
	
	public static void main(String[] args) {
		System.setProperty("java.net.preferIPv4Stack", "true");//只使用IPV4
		MulticastClient multicastClient = new MulticastClient(new InetSocketAddress("224.1.1.1", 9000));
		multicastClient.run();
	}
	
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章