UDP程序设计

UDP效率高于TCP,UDP是单向操作,无交互动作(只发送数据但不校验,或者只接收数据但不反馈)

数据包DatagramPacket
格式:DatagramPacket(byte[] buf包数据,int length包长度,InetAddress address目的地址,int port目的端口)
包裹(数据包)打好以后,交给快递员(套接字socket)发送(send)出去

数据包套接字DatagramSocket
格式:DatagramSocket socket=new DatagramSocket(int port,InetAddress addr) //绑定本地的端口、IP地址
socket.send(DatagramPacket) //发送数据包
socket.receive(DatagramPacket) //接收数据包

多点广播套接字 MulticastSocket(DatagramSocket的子类)
格式:MulticastSocket socket=new MulticastSocket(int端口)
joinGroup(InetAddress) 加入广播组
leaveGroup(InetAddress) 离开广播组
socket.send(DatagramPacket) //发送数据包
socket.receive(DatagramPacket) //接收数据包

案例:BroadCast广播数据,Receiver接收数据

public class BroadCast {
    Thread thread;//实现持续的发送广播

    int port = 9898;//端口
    InetAddress address;//网络地址对象
    MulticastSocket socket;//多点广播套接字对象

    public BroadCast() {//构造方法
        try {
            //实例化,指定主机所在的组,组的范围224.0.0.0~224.255.255.255
            address = InetAddress.getByName("224.255.10.0");
            socket = new MulticastSocket(port);//多点广播
            //socket.setTimeToLive(1);//广播的范围是本地网络
            socket.joinGroup(address);//加入广播组
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }
        thread = new Thread(new MyRunnable());
        thread.start();
    }

    class MyRunnable implements Runnable {
        public void run() {
            while (true) {
                Date date = new Date();//创建时间对象
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");//时间格式
                String broadcast = "现在时间:" + sdf.format(date);//格式化时间
                byte data[] = broadcast.getBytes();//存储要发送的内容
                //数据包。内容、长度、地址、端口
                DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
                System.out.println(new String(data));//控制台输出,方便自己查看
                try {
                    socket.send(packet);//发送数据
                    thread.sleep(2000);//休眠2s

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        new BroadCast();//实例化构造方法
    }
}
public class Receiver extends JFrame {//窗体类
    JButton begin = new JButton("开始接收");
    JButton stop = new JButton("停止接收");
    JTextArea ta1 = new JTextArea(10, 10);
    JTextArea ta2 = new JTextArea(10, 10);
    boolean b = true;//是否接收广播
    Thread thread;//线程,用来执行广播接收操作

    int port = 9898;//端口号
    InetAddress group;//网络地址对象
    MulticastSocket socket;//多点广播套接字对象
    
    public Receiver() {//窗体类的方法
        //super("广播");
        setTitle("广播");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setBounds(100, 50, 460, 200);
        //按钮面板
        JPanel panelButton = new JPanel();
        panelButton.add(begin);
        panelButton.add(stop);
        add(panelButton, BorderLayout.NORTH);
        //文本域面板
        JPanel panelTextArea = new JPanel();
        panelTextArea.setLayout(new GridLayout(1, 2));
        panelTextArea.add(ta1);
        final JScrollPane scrollPane = new JScrollPane(ta2);//为右边的文本域添加滚动条
        panelTextArea.add(scrollPane);
        add(panelTextArea, BorderLayout.CENTER);
        validate();//刷新

        begin.addActionListener(new MyButtonAction());//调用按钮事件
        stop.addActionListener(new MyButtonAction());

        try {
            group = InetAddress.getByName("224.255.10.0");//指定接收地址
            socket = new MulticastSocket(port);//绑定多点广播套接字
            socket.joinGroup(group);//加入广播组
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        thread = new Thread();//创建线程。否则if (!thread.isAlive())提示空指针
        setVisible(true);
    }

    class MyButtonAction implements ActionListener {//自定义按钮事件

        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == begin) {
                begin.setBackground(Color.GREEN);//按钮变绿
                stop.setBackground(null);
                if (!thread.isAlive()) {//线程是否处于活动状态
                    thread = new Thread(new MyRunnable());//调用接口
                    b = true;//接收数据
                }
                thread.start();
            }
            if (e.getSource() == stop) {
                stop.setBackground(Color.GREEN);
                begin.setBackground(null);
                b = false;//停止接收数据
            }
        }
    }

    class MyRunnable implements Runnable {//自定义接口,实现文本域中显示内容

        public void run() {
            while (b) {
                byte data[] = new byte[1024];//byte数组,存储接收的数据
                DatagramPacket packet = new DatagramPacket(data, data.length, group, port);//待接收的数据包
                try {
                    socket.receive(packet);//接收数据包
                    String message = new String(packet.getData(), 0, packet.getLength());//获取数据包内容,转换为字符串
                    //将接收的内容显示在文本域
                    ta1.setText("正在接收:\n" + message);
                    ta2.append(message + "\n");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        new Receiver();
    }
}

 

posted @ 2018-09-14 12:32  夕西行  阅读(190)  评论(0编辑  收藏  举报