• 第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,这类地址并不代表某个特定主机的位置。加入到同一个组的主机可以在某个端口上广播信息,也可以在某个端口上接收信息。

  • 相关阅读:
    opengl像素格式管理
    opengl的体系结构
    符号文件——Windows 应用程序调试必备
    [Study Note] Patterns in Practice 20100404
    “在我的机器上可以运行”症状自查(Windows编程)
    [Study Note] Patterns in Practice 20100402
    [Study Note] Patterns in Practice 20100406
    [Study Note] Design and Testability 20100410
    [Study Note] Patterns in Practice 20100403
    [Study Note] Design and Testability 20100411
  • 原文地址:https://www.cnblogs.com/chamie/p/4715301.html
Copyright © 2020-2023  润新知