UDP/TCP 协议

UDP: User Datagram Protocol  用户数据报协议 是一种无连接的协议。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。

使用UDP: 在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多


UDP广播:广播使用广播地址255.255.255.255,将消息发送到在同一广播网络上的每个主机。值得强调的是:本地广播信息是不会被路由器转发。当然这是十分容易理解的,因为如果路由器转发了广播信息,那么势必会引起网络瘫痪。这也是为什么IP协议的设计者故意没有定义互联网范围的广播机制。其实广播顾名思义,就是想局域网内所有的人说话,但是广播还是要指明接收者的端口号的,因为不可能接受者的所有端口都来收听广播。

发送接收 demo:

    public static void sendBroadcast(byte[] data, int port) throws Exception{
        DatagramSocket socket = new DatagramSocket();
        socket.setBroadcast(true);
        DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("255.255.255.255"), port);
        socket.send(packet);
    }

    public static void receiveBoradcast(int port) {
        new Thread(new Runnable() {

            DatagramSocket socket;

            @Override
            public void run() {
                while (true) {
                    try {
                        receive(port);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            public void receive(int port) throws Exception{
                if (socket == null || socket.isClosed()) {
                    socket = new DatagramSocket(port);
                    socket.setBroadcast(true);
                }

                byte[] buffer = new byte[1024 * 100];
                DatagramPacket packet = new DatagramPacket(buffer , buffer.length);
                socket.receive(packet);
                String data = new String(packet.getData(), 0, packet.getLength());
                Log.i("receiver", data);
                socket.close();
            }

        }).start();
    }


Netty 实现 demo

public class Broadcast {

    Channel udpChannel;

    public void send(String data) throws Exception{
        if(udpChannel != null) {
            udpChannel.writeAndFlush(data);
        }
    }

    public void init(int port) {
        NioEventLoopGroup group = new NioEventLoopGroup();
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                .channel(NioDatagramChannel.class)
                .option(ChannelOption.SO_BROADCAST, true)
                .handler(new MessageToMessageEncoder<String>() {
                    @Override
                    protected void encode(ChannelHandlerContext ctx, String msg, List<Object> out) throws Exception {
                        InetSocketAddress remoteAddress = new InetSocketAddress("255.255.255.255", port);
                        out.add(new DatagramPacket(Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8), remoteAddress));
                    }
                });
        udpChannel = bootstrap.bind(0).syncUninterruptibly().channel();
    }

}

public class BroadcastReceiver {

    public void start(int port){
        Bootstrap b = new Bootstrap();
        NioEventLoopGroup group = new NioEventLoopGroup();
        try {
            b.group(group)
                    .channel(NioDatagramChannel.class)
                    .option(ChannelOption.SO_BROADCAST, true)
                    .handler(new SimpleChannelInboundHandler<DatagramPacket>() {

                        @Override
                        protected void messageReceived(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
                            String req = packet.content().toString(CharsetUtil.UTF_8);
                            System.out.println(req);
                        }
                    });
            b.bind(port).sync().channel().closeFuture().await();
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            group.shutdownGracefully();
        }
    }

}

多播  

多播数据报套接字类用于发送和接收 IP 多播包。MulticastSocket 是一种 (UDP) DatagramSocket,它具有加入 Internet 上其他多播主机的“组”的附加功能。

多播组通过 D 类 IP 地址和标准 UDP 端口号指定。D 类 IP 地址在 224.0.0.0 和 239.255.255.255 的范围内(包括两者)。地址 224.0.0.0 被保留,不应使用。

多播 demo

public class MultiBroadcast {

    public void startReveive(String host, int port) {

        new Thread(new Runnable() {

            MulticastSocket ms;

            private void receive(String host, int port) throws Exception{
                byte[] buf = new byte[1024 * 100];
                if(ms == null || ms.isClosed()) {
                    ms = new MulticastSocket(port);
                    DatagramPacket dp = new DatagramPacket(buf, buf.length);
                    InetAddress group = InetAddress.getByName(host);
                    ms.joinGroup(group);
                    ms.receive(dp);
                }

                Log.i("receiver", new String(buf));
                ms.close();
            }

            @Override
            public void run() {
                while (true) {
                    try {
                        receive(host, port);
                        Thread.sleep(100);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    public void send(String host, int port, String message) throws Exception{
        InetAddress group = InetAddress.getByName(host);
        MulticastSocket s = new MulticastSocket();
        s.joinGroup(group);
        DatagramPacket dp = new DatagramPacket(message.getBytes(),message.length(), group,port);
        s.send(dp);
        s.close();
    }

}

单播

public class UnicastBroadcast {

    public void send(String host, int port, byte[] message) throws Exception{
        //sending data to host and its port
        InetAddress address = InetAddress.getByName(host);
        // Initialize a datagram packet with data and address
        DatagramPacket packet = new DatagramPacket(message, message.length, address, port);
        // Create a datagram socket, send the packet through it, close it.
        DatagramSocket dsocket = new DatagramSocket();
        dsocket.send(packet);
        dsocket.close();
    }

    public void startReceive() {
        new Thread(new Runnable() {

            DatagramSocket dsocket;

            @Override
            public void run() {

            }

            private void receive(int port) throws Exception{

                byte[] buffer = new byte[2048];
                if(dsocket == null || dsocket.isClosed()) {
                    //receiving data from its port
                    dsocket = new DatagramSocket(port);
                    // Create a buffer to read datagrams into. If a
                    // packet is larger than this buffer, the
                    // excess will simply be discarded!

                    // Create a packet to receive data into the buffer
                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

                    // Wait to receive a datagram
                    dsocket.receive(packet);
                    // Convert the contents to a string, and display them
                    String msg = new String(buffer);
                    System.out.println(packet.getAddress().getHostName() + ": " + msg);
                }
                
                dsocket.close();

            }

        }).start();
    }

}



Netty dmo

http://colobu.com/2014/10/21/udp-and-unicast-multicast-broadcast-anycast/#单播





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值