使用Java实现基于UDP协议的网络通信

UDP协议是一种不可靠的网络协议,它在通信实例的两端个建立一个Socket,但这两个Socket之间没有虚拟链路,这两个Socket只是发送、接收数据报的对象。Java提供了DatagramSocket对象作为基于UDP协议的Socket,使用DatagramPacket代表DatagramSocket发送、接收数据报。
可以认为UDP协议的Socket类似于码头,数据报则类似于集装箱;码头的作用就是负责发送、接收集装箱,而DatagramSocket的作用则是发送、就收数据报。因此对于通信双方而言,没有所谓的客户端和服务器端的概念。因为UDP协议是面向非连接的协议,没有建立连接过程,因此它的通信效率很好;但可靠性就不如TCP协议。
使用DatagramSocket发送、接收数据
DatagramSocket的构造器:

  • DatagramSocket():创建一个DatagramSocket实例,绑定在本机默认IP地址、本机所有可用端口中随机选择某个端口。
  • DatagramSocket(int port):绑定到本机默认IP地址,指定端口。
  • DatagramSocket(int port,InetAddress laddr):指定IP地址和端口。
    接收和发送数据的方法:
  • receive(DatagramPocket p):从该DatagramSocket中接收数据报。
  • send(DatagramPocket p):以该DatagramSocket对象向外发送数据报。
    我们还需要DatagramPocket决定数据报的目的地:
  • DatagramPocket(byte[] buf,int length):以一个空的byte数组创建DatagramPocket对象,该对象是用于接收DatagramSocket中的数据。
  • DatagramPocket(byte[] buf,int length,InetAddress addr,int port):包含数据的数组,并指定IP地址和端口来决定数据报的目的地。
  • DatagramPocket(byte[] buf,int offset,int length):数据从offset开始,最多存放length个字节。
  • DatagramPocket(byte[] buf,int offset,int length,InetAddress addr,int port):指定数据,IP地址和端口。
    代码:
    server端:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Scanner;

public class UDPServer {
    private DatagramSocket socket;  //实现UDP编码的工具包
    private DatagramPacket packet;  //封装数据报的类
    private Scanner scanner;
    private final int port = 5676;

    public UDPServer() {
        try {
            socket = new DatagramSocket(port);  //server 进程和该端口号绑定
            byte[] bytes = new byte[1024];
            packet = new DatagramPacket(bytes, 0, bytes.length);
            scanner = new Scanner(System.in);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public void startSever() {  //服务器启动之后的业务逻辑
        //(1)接收用户的请求
        try {
            while(true) {
                socket.receive(packet);  //接收用户请求的
                //处理收到的数据
                String str = new String(packet.getData(), 0, packet.getLength());
                System.out.println("接收到客户端发送的数据为: " + str);
                //根据收到的信息做出对应的逻辑处理
                //然后将处理之后的结果返回给用户
                System.out.println("请输入你向客户端回复信息 : ");
                String s = scanner.nextLine();
                byte[] bytes = s.getBytes();
                //数据如何知道应该发给谁呢
                //获取到  发出请求的用户的信息
                DatagramPacket sendpacket = new DatagramPacket(bytes, 0, bytes.length,
                        packet.getAddress(), packet.getPort());
//        client 对应的ip 和port     packet.getAddress(), packet.getPort()
                socket.send(sendpacket);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            socket.close();
        }
    }

    public static void main(String[] args) {
        new UDPServer().startSever();
    }
}

client端:

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

public class UDPClient {
    private final String IP = "127.0.0.1";  //代词
    private final int port = 5676;
    private DatagramSocket socket;  //实现UDP编码的工具包
    private DatagramPacket packet;  //封装数据报的类
    private Scanner scanner;

    public UDPClient() {
        try {
            socket = new DatagramSocket();  //server 进程和该端口号绑定
            byte[] bytes = new byte[1024];
            packet = new DatagramPacket(bytes, 0, bytes.length);
            scanner = new Scanner(System.in);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public void startClient() {  //客户端启动之后的业务逻辑
            try {
                while(true) {
                    System.out.println("请输入你的请求 : ");
                    String s = scanner.nextLine();
                    byte[] bytes1 = s.getBytes();
                    //数据如何知道应该发给谁呢
                    //获取到  发出请求的用户的信息
                    DatagramPacket sendpacket = new DatagramPacket(bytes1, 0, bytes1.length,
                            InetAddress.getByName(IP), port);
                    socket.send(sendpacket);
                    if(s.equals("exit")){
                        break;
                    }
                    socket.receive(packet);  //接收用户请求的

                    //处理收到的数据
                    String str = new String(packet.getData(), 0, packet.getLength());
                    System.out.println("接收到服务器回复的数据为: " + str);
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                socket.close();
            }
    }

    public static void main(String[] args) {
        new UDPClient().startClient();
    }
}

运行结果:
在这里插入图片描述在这里插入图片描述

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值