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(); } }