zoukankan      html  css  js  c++  java
  • 第19章 网络通信----UDP程序设计基础

    用户数据报协议(UDP)是网络信息传输的另一种形式。

    基于UDP通信的基本模式如下:

      (1)将数据打包(称为数据包),然后将数据包发往目的地。

      发送数据包:

      使用DatagramSocket()创建一个数据包套接字;

      使用DatagramPacket(byte[] buf,int offset,int length,InetAddress address,int port)创建要发送的数据包;

      使用DatagramSocket类的send()方法发送数据包。

      (2)接收别人发来的数据包,然后查看数据包。

      接收数据包:

      使用DatagramSocket(int port)创建数据包套接字,绑定到指定的端口;

      使用DatagramPacket(byte[] buf,int length)创建字节数组来接收数据包;

      使用DatagramPacket类的receive()方法接收UDP包。

    1、DatagramPacket类

    2、DatagramSocket类

    3、UDP网络程序

    下面创建一个广播数据报程序。广播数据报是一种较新的技术,类似于电台广播,广播电台需要在指定的波段和频率上广播信息,收听者也要将收音机调到指定的波段、频率才可以收听广播内容。

    例如:主机不断地重复播出节目预报,可以保证加入到同一组的主机随时可接收到广播信息。接收者将正在接收的信息放在一个文本域中,并将接收的全部信息放在另一个文本域中。

    (1)广播主机程序不断地向外播出信息,代码如下:

    import java.net.*;
    
    public class Weather extends Thread { // 创建类。该类为多线程执行程序
        String weather = "节目预报:八点有大型晚会,请收听";
        int port = 9898; // 定义端口
        InetAddress iaddress = null; // 创建InetAddress对象
        MulticastSocket socket = null; // 声明多点广播套接字
        
        Weather() { // 构造方法
            try {
                // 实例化InetAddress,指定地址
                iaddress = InetAddress.getByName("224.255.10.0");
                socket = new MulticastSocket(port); // 实例化多点广播套接字
                socket.setTimeToLive(1); // 指定发送范围是本地网络
                socket.joinGroup(iaddress); // 加入广播组
            } catch (Exception e) {
                e.printStackTrace(); // 输出异常信息
            }
        }
        
        public void run() { // run()方法
            while (true) {
                DatagramPacket packet = null; // 声明DatagramPacket对象
                byte data[] = weather.getBytes(); // 声明字节数组
                // 将数据打包
                packet = new DatagramPacket(data, data.length, iaddress, port);
                System.out.println(new String(data)); // 将广播信息输出
                try {
                    socket.send(packet); // 发送数据
                    sleep(3000); // 线程休眠
                } catch (Exception e) {
                    e.printStackTrace(); // 输出异常信息
                }
            }
        }
        
        public static void main(String[] args) { // 主方法
            Weather w = new Weather(); // 创建本类对象
            w.start(); // 启动线程
        }
    }

    (2)接收广播程序:单击“开始接收”按钮,系统开始接收主机播出的信息;单击“停止接收”按钮,系统会停止广播主机播出的信息。

    import java.awt.*;
    import java.awt.event.*;
    import java.net.*;
    
    import javax.swing.*;
    
    public class Receive extends JFrame implements Runnable, ActionListener {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        int port; // 定义int型变量
        InetAddress group = null; // 声明InetAddress对象
        MulticastSocket socket = null; // 创建多点广播套接字对象
        JButton ince = new JButton("开始接收"); // 创建按钮对象
        JButton stop = new JButton("停止接收");
        JTextArea inceAr = new JTextArea(10, 10); // 显示接收广播的文本域
        JTextArea inced = new JTextArea(10, 10);
        Thread thread; // 创建Thread对象
        boolean b = false; // 创建boolean型变量
        
        public Receive() { // 构造方法
            super("广播数据报"); // 调用父类方法
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            thread = new Thread(this);
            ince.addActionListener(this); // 绑定按钮ince的单击事件
            stop.addActionListener(this); // 绑定按钮stop的单击事件
            inceAr.setForeground(Color.blue); // 指定文本域中文字颜色
            JPanel north = new JPanel(); // 创建Jpane对象
            north.add(ince); // 将按钮添加到面板north上
            north.add(stop);
            add(north, BorderLayout.NORTH); // 将north放置在窗体的上部
            JPanel center = new JPanel(); // 创建面板对象center
            center.setLayout(new GridLayout(1, 2)); // 设置面板布局
            center.add(inceAr); // 将文本域添加到面板上
    
            final JScrollPane scrollPane = new JScrollPane();
            center.add(scrollPane);
            scrollPane.setViewportView(inced);
            add(center, BorderLayout.CENTER); // 设置面板布局
            validate(); // 刷新
            port = 9898; // 设置端口号
            try {
                group = InetAddress.getByName("224.255.10.0"); // 指定接收地址
                socket = new MulticastSocket(port); // 绑定多点广播套接字
                socket.joinGroup(group); // 加入广播组
            } catch (Exception e) {
                e.printStackTrace(); // 输出异常信息
            }
            setBounds(100, 50, 360, 380); // 设置布局
            setVisible(true); // 将窗体设置为显示状态
        }
        
        public void run() { // run()方法
            while (true) {
                byte data[] = new byte[1024]; // 创建byte数组
                DatagramPacket packet = null; // 创建DatagramPacket对象
                // 待接收的数据包
                packet = new DatagramPacket(data, data.length, group, port);
                try {
                    socket.receive(packet); // 接收数据包
                    String message = new String(packet.getData(), 0, packet
                            .getLength()); // 获取数据包中内容
                    // 将接收内容显示在文本域中
                    inceAr.setText("正在接收的内容:
    " + message);
                    inced.append(message + "
    "); // 每条信息为一行
                } catch (Exception e) {
                    e.printStackTrace(); // 输出异常信息
                }
                if (b == true) { // 当变量等于true时,退出循环
                    break;
                }
            }
        }
        
        public void actionPerformed(ActionEvent e) { // 单击事件
            if (e.getSource() == ince) { // 单击按钮ince触发的事件
                ince.setBackground(Color.red); // 设置按钮颜色
                stop.setBackground(Color.yellow);
                if (!(thread.isAlive())) { // 如线程不处于“新建状态”
                    thread = new Thread(this); // 实例化Thread对象
                }
                thread.start(); // 启动线程
                b = false; // 设置变量值
            }
            if (e.getSource() == stop) { // 单击按钮stop触发的事件
                ince.setBackground(Color.yellow); // 设置按钮颜色
                stop.setBackground(Color.red);
                b = true; // 设置变量值s
            }
        }
        
        public static void main(String[] args) { // 主方法
            Receive rec = new Receive(); // 创建本类对象
            rec.setSize(460, 200); // 设置窗体大小
        }
    }

    说明:要广播或接收广播的主机地址必须加入到一个组内,地址范围为224.0.0.0~224.255.255.255,这类地址并不代表某个特定主机的位置。加入到同一个组的主机可以在某个端口上广播信息,也可以在某个端口上接收信息。

  • 相关阅读:
    火狐插件火狐黑客插件将Firefox变成黑客工具的七个插件
    memcache安装环境:WINDOWS 7
    PHP正则表达式
    968. 监控二叉树 力扣(困难) dfs 官方说DP
    375. 猜数字大小 II 力扣(中等) 区间动态规划、记忆化搜索
    629. K个逆序对数组 力扣(困难) 区间动态规划
    剑指 Offer 51. 数组中的逆序对 力扣(困难) 巧用归并排序算法
    488. 祖玛游戏 力扣(困难) dfs
    16. 最接近的三数之和 力扣(中等) 双指针
    319. 灯泡开关 力扣(中等) 数论
  • 原文地址:https://www.cnblogs.com/chamie/p/4715301.html
Copyright © 2011-2022 走看看