欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > UDP协议程序设计

UDP协议程序设计

2025/3/10 6:02:46 来源:https://blog.csdn.net/weixin_74141222/article/details/141777062  浏览:    关键词:UDP协议程序设计

文章目录

  • 前言
  • 一、UDP程序设计是什么?
  • 二、使用步骤
    • 1.数据包套接字与多播套接字
    • 2.数据报包
    • 3.实操展示
  • 总结

前言

        UDP协议程序相对于TCP协议,就是一个广播喇叭给全村人听和两个人说悄悄话的差别。因此UDP的数据传输效率比TCP高,可以同时分享给所有在场的人。缺点就是不能保证数据能完整地传送到接收方那里,这个就像喇叭一样了,谁知道对方听没听,UDP只管广播。UPD和TCP协议都可以看作数据通讯协议。


一、UDP程序设计是什么?

        UDP程序设计是指使用用户数据报协议(UDP)进行网络通信的程序设计。

        UDP 是一种无连接的协议,它提供了一种简单的、不可靠的数据传输服务。与传输控制协议(TCP)相比,UDP 不提供可靠的数据传输和流控制机制,但具有较低的延迟和较小的数据传输量。

        UDP程序中,套接字负责接收或发送数据包,数据包负责保存数据内容,就像外卖小哥从一家店拿了外卖运送到各个门口一样,套接字是小哥,数据包是外卖。数据包套接字和多播套接字,两个套接字都是一回事,它们都是实现主机接收或发送数据包的类,只不过一个是父类一个是子类的关系。数

二、使用步骤

        UDP协议的使用如下:

        发送数据包

        (1)使用MulticastSocket()创建数据包套接字对象(记得绑定接口)。

        (2)将该数据包套接字使用joinGroup(InetAddress inet)方法加入指定的广播组地址(提前创建InetAddress对象,广播组地址范围:224.0.0.0~239.255.255.255)。

        (3)使用DatagramPacket()的构造方法创建要发送的数据包对象。

        (4)使用DatagramSocket()的send(DatagramPacket 数据包对象)方法发送数据包。

        接收数据包

        (1)使用MulticastSocket(int port)创建数据包套接字,绑定到指定端口。

        (2)将该数据包套接字使用joinGroup(InetAddress inet)方法加入指定广播方的广播组地址。

        (3)使用DatagramPacket(byte[] buf,int length)创建字节数组,接收数据包对象。

        (4)使用DatagramSocket类的receive(DatagramPacket 数据包对象)方法接收数据包。

1.数据包套接字与多播套接字

        (1)数据包套接字(DatagramSocket类)

        java.net包的DatagramSocket类用于创建可以发送和接收数据包的套接字。

        DatagramSocket类的构造方法:

new DatagramSocket();
//该构造方法创建DatagramSocket对象,创建数据包套接字。new DatagramSocket(int port);
//该构造方法在创建数据包套接字对象的同时,并绑定了套接字的接口。new DatagramSocket(int port,InetAddress address);
//该构造方法在创建数据包套接字对象的同时,并绑定了套接字的接口和指定的地址。

        创建好DatagramSocket对象,绑定了接口,再使用joinGroup()方法(已经使用过构造方法绑定地址的不用使用此方法),就可以发送和接收数据包了。 

DatagramSocket类的常用方法
方法功能描述返回值
send(DatagramPacket packet)发送指定的数据报到广播组void
receive(DatagramPacket packet)从广播组中接收数据报并将其存储在指定的数据包中void
 close()关闭DatagramSocket对象,关闭套接字void
setSoTimeout(int timeout)设置套接字的读取超时时间(以毫秒为单位)void
getLocalPort()返回此套接字绑定到的本地端口号int
connect(InetAddress address, int port)将此套接字连接到指定的远程地址和端口号void
disconnect()断开与远程地址的连接void
getInetAddress()返回与此套接字连接的远程主机的IP地址InetAddress
getPort()返回与此套接字连接的远程主机的端口号int
isClosed()检查套接字是否已关闭boolean
isConnected()检查套接字是否已连接到远程主机boolean

         DatagramSocket()类的receive()方法接收数据时,如果还没有可以接收的数据,正常情况下receive()方法将阻塞,一直等到网络上有数据传来,receive()方法接收到该数据并返回。如果receive()方法没有阻塞,肯定程序出了问题,多数情况下时因为使用了一个被其他程序占用的端口号。

        (2)多播套接字(MulticastSocket类)

MulticastSocket extends DatagramSocket

        MulticastSocket类是上面的DatagramSocket的子类,这意味着MulticastSocket类都能使用DatagramSocket类的常用方法了,由于该子类有更多的方法供使用,所以在实际编程中,用MuticastSocket创建套接字更多一些。

        MulticastSocket类的构造方法:

new MulticastSocket();
//创建一个未绑定到任何本地端口的MulticastSocket对象。new MulticastSocket(int port);
//创建一个绑定到指定本地端口的MulticastSocket对象。

        什么情况下使用MulticastSocket类?

        (1)多播通信:应用程序需要向多个客户端发送数据,使用MulticastSocket更为合适。

        (2)简化的多播管理:MulticastSocket提供了方便的方法,如 joinGroup() 和 leaveGroup(),使得管理多播组变得简单。使用这些方法,你可以轻松地加入或离开多播组,而不需要手动处理组地址和端口。

        (3)自动处理:使用 MulticastSocket 时,系统会自动处理多播特性,例如适当的网络路由和数据包的复制,这样你就不需要担心底层的多播实现细节。

        (4)适用场景:在局域网内的实时数据传输(如视频流、在线游戏等),那么 MulticastSocket是更好的选择

MulticastSocket类的常用方法
方法功能描述返回值
joinGroup(InetAddress group)将套接字加入到指定的多播组,允许套接字开始接收或发送到该组的多播数据void
joinGroup(SocketAddress mcastaddr)通过指定的 SocketAddress 来加入多播组void
leaveGroup(InetAddress group)将套接字从指定的多播组中移除,停止接收或发送该组的多播数据void
leaveGroup(SocketAddress mcastaddr)通过指定的 SocketAddress 来离开多播组void
setTImeToLive(int tti)设置数据包的生存时间(TTL),用于控制多播数据包在网络中的跳数。TTL 的值通常在 1 到 255 之间void
getTimeToLive()获取当前设置的生存时间(TTL)值int
getLoopbackMode(boolean loopbackMode)设置是否允许将发送到多播组的数据包环回到本地的套接字void
getLoopbackMode()获取当前的环回模式设置boolean

        以上MulticastSocket类的常用方法,并没有写上继承自父类DatagramSocket类的方法,但该子类仍可以使用。子类的这些特有的常用方法使得MulticastSocket能够有效地管理多播组的加入和离开,以及控制多播数据的传输特性。

2.数据报包

        数据包(DatagramPackage类)

        java.net包的DatagramPacket类用于创建数据包对象,UDP程序中运输数据的包裹。

        DatagramPacket类的构造方法:

new DatagramPackage(byte[] buf,int length);
//该构造方法在创建数据包对象的同时,指定了数据包的数据内容和数据长度new DatagramPackage(byte[] buf,int length, InetAddress address,int port);
//该构造方法在创建数据包对象的同时,指定了数据包的数据内容和数据长度,
//还有数据包发送的目标地址和端口

        创建数据包对象时,一般使用第二个构造方法,直接绑定UDP地址和端口,省事。 

DatagramPacket类的常用方法
方法功能描述返回值
getData()返回接收数据包的缓冲区byte[]
getLength()返回接收数据包的数据长度int
getAddress()返回发送数据包的目标地址InetAddress
getPort()返回发送数据包的目标端口int
setData(byte[] buf)设置发送数据包的缓冲区void
setLength(int length)设置发送数据包的数据长度void
setAddress(InetAddress address)设置接收数据包的目标地址void
setPort(int port)设置接收数据包的目标端口void

        以上方法都是用于调整和设置数据包的发送地址、接口,数据包的大小,字节长度等数据。 

3.实操展示

        项目设计:实时广播当地的天气,接收方可以为许多当地人的手机,必须实时且同步。

        广播组程序:使用MulticastSocket类创建多播套接字,构造方法中绑定接口和加入UDP地址;创建线程,使用Date类,格式化好后,打包到数据包对象中,套接字使用方法发送数据包到指定UDP地址处。

import java.io.IOException;
import java.lang.Thread;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.util.Date;
import java.text.SimpleDateFormat;
public class Sender extends Thread{int port = 9898;    //端口InetAddress group;  //广播组地址对象MulticastSocket socket; //多播数据包套接字@SuppressWarnings("deprecation")public Sender(){//广播组地址范围:224.0.0.0~239.255.255.255try{group = InetAddress.getByName("224.255.1.1");   //指定广播组地址socket = new MulticastSocket(port);    //套接字实例化并绑定接口socket.joinGroup(group);    //套接字加入UDP地址,可以向该地址接收或发送消息}catch(UnknownHostException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}}public void run(){while (true) {DatagramPacket packet;Date date = new Date();SimpleDateFormat sf = new SimpleDateFormat("HH:mm:ss");String message = "["+sf.format(date)+"] 天气预报:当前天气,多云。";byte data[] =message.getBytes();packet = new DatagramPacket(data, data.length, group,port); //创建数据报,实例化,将上述数据存入数据包中,绑定了发送的UDP地址和接口try {socket.send(packet);    //向UDP地址发送该数据包System.out.println("Sending: " + message);Thread.sleep(1000);} catch (IOException e) {e.printStackTrace();} catch(InterruptedException e){e.printStackTrace();}}}public static void main(String[] args) {Sender sender = new Sender();    //构造方法解决了套接字的问题,简化了代码sender.start();    //启动线程}}

        客户端程序:接收类继承JFrame类,在构造方法中调用超类,创建窗口,实现界面交互(接收或中止接收广播消息),文本域中显示接收到的消息;实现Runnable接口,创建数据包对象,用套接字的方法和while循环不断接收指定UDP地址的广播消息;实现了ActionListener接口,为两个按钮添加监听事件和交互反馈,“接收消息”按钮被点击时,启动线程的start()方法,接收消息。

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;import javax.swing.*;
import java.lang.Runnable;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;@SuppressWarnings("deprecation")
public class Receiver extends JFrame implements Runnable,ActionListener{JButton ince = new JButton("接收消息");JButton stop = new JButton("停止接收");JTextArea inceAr = new JTextArea(10,10);JTextArea inced = new JTextArea(10, 10);Thread thread;boolean getMessage = true; //是否接收广播int port = 9898;InetAddress group;MulticastSocket socket;public Receiver(){super("广播数据报");    //引用超类构造方法,设置窗体标题setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);    //WindowConstants表示多个窗口的关闭方式inceAr.setForeground(Color.BLUE);JPanel north = new JPanel();north.add(ince);    //将按钮添加到面板north上north.add(stop);add(north,BorderLayout.NORTH);JPanel center = new JPanel();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(); //重新验证容器中的组件,刷新组件setBounds(100, 50, 640, 380);setVisible(true);ince.addActionListener(this);stop.addActionListener(this);try{group = InetAddress.getByName("224.255.1.1");  //指定广播组地址socket = new MulticastSocket(port);     //实例化多播数据包套接字socket.joinGroup(group);} catch (IOException e){e.printStackTrace();}thread = new Thread(this);}@Overridepublic void run(){while (getMessage) {byte data[] = new byte[1024];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+"\n");} catch (IOException e) {e.printStackTrace();}}}@Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource()==ince){ince.setBackground(Color.green);stop.setBackground(Color.red);if(!thread.isAlive()){thread = new Thread(this);getMessage = true;}thread.start();    }if(e.getSource()==stop){ince.setBackground(Color.red);stop.setBackground(Color.green);getMessage = false;}}public static void main(String[] args) {   new Receiver();}
}

        运行结果:

        广播组程序:

        

        如图所示,广播组程序向指定的UDP地址每隔一秒就发送一次天气播报。 

        客户端程序(当广播组程序启动后才能运行):

        

        如图所示,可以有多个客户端,同时且同步的获取到广播组广播的信息,只要它们连接的是同一个接口和UDP地址。


总结

        以上就是对UDP程序设计的简单介绍,本文简单介绍了如何搭建UDP程序,该程序在互联网通讯中的应用涉及面十分广泛。如果有疑问或指正的地方,欢迎读者在评论区中留言。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词