UDP数据报套接字编程

举报
bug郭 发表于 2022/09/30 23:46:26 2022/09/30
【摘要】 大家好,我是bug郭,一名双非科班的在校大学生。对C/JAVA、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流作者简介:CSDN java领域新星创作者blog.csdn.net/bug…掘金LV3用户 juejin.cn/user/bug…阿里云社区专家博主,星级博主,developer.a...

大家好,我是bug郭,一名双非科班的在校大学生。对C/JAVA、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流

作者简介:

UDP数据报套接字编程案例

  • 回显服务客户端和服务器

我们通过UDP socket 实现一个回显服务的服务器和客户端,就是客户端给服务器发信息,服务器会转发刚刚发送的信息给客户端!
通过这个案例,可以学习UDP网络编程的流程!

//回显服务器代码
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class UdpEchoServer {
    //1.源端口 服务器的端口号 需要自己设置
    //2.源IP 服务器主机的IP
    //3.目的端口 客户端的端口号 服务器接收的数据报中有
    //4.目的IP 客户端IP 服务器接收的数据报中!
    //5.协议类型 UDP

    //编程前提 创建socket实例 用于操作系统中的socket api
     DatagramSocket socket = null;
    public UdpEchoServer(int port) throws SocketException { //设置服务器的端口号
        socket = new DatagramSocket(port);
    }
    //启动服务器
    public void start() throws IOException {
        System.out.println("启动服务器!");
        //UDP不需要建立连接,直接接收请求即可!
        while (true){
            //为了接收数据 创建了一个指定空间大小的空数据报!
            DatagramPacket requestPacket = new  DatagramPacket(new byte[1024],1024);
            socket.receive(requestPacket);//输出型参数 //request 就接收到了数据!
            //获取请求,将数据报转化成字符串!
            //指定获取数据的起始位置和长度还有编码格式
            String request = new String(requestPacket.getData(),0,requestPacket.getLength(),"UTF-8");
            //根据请求计算响应
            String response = process(request);
            //将响应封装成数据报
            //转化成字节数组,字节大小,目的端口和地址getSocktAddress!
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
            socket.send(responsePacket);
            //将客户端的ip 端口 请求 响应 打印
            System.out.printf("[%s,%d] req:%s res:%s\n",requestPacket.getAddress(),requestPacket.getPort(),request,response);
        }
    }

    public String  process(String request) {
        //回显服务,直接返回请求
        return  request;
    }

    public static void main(String[] args) throws IOException {
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090); //设置服务器端口 9090
        udpEchoServer.start(); //启动服务器!
    }
}

//回显客户端代码
import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class UdpEchoClient {
    //1.源IP 客户端本机IP
    //2.源端口 客户端端口 可以由系统随机分配
    //3.目的IP 服务器IP
    //4.目的端口 服务器端口
    //5.协议类型 UDP
    DatagramSocket socket= null;
    String serverIp =null;
    int serverPort = 0;
    public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
        //服务器不需要指定端口,系统分配!
        socket = new DatagramSocket();
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }
    //启动客户端
    public void start() throws IOException {
        System.out.println("启动客户端");
        Scanner scanner = new Scanner(System.in);
        while(true){
            //写请求 从控制台输入字符!
            System.out.print("->");
            String request = scanner.nextLine();
            //将请求封装成数据报
            //这里需要将目的IP和端口传入! 并且需要调用InetAddress.getByName(serverIp)传入目的IP
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);
            //发送请求给客户端
            socket.send(requestPacket);
            //接收请求
            //给出接收请求的空数据报
            DatagramPacket responsePacket = new DatagramPacket(new byte[1024],1024);
            socket.receive(responsePacket);
            //将收到的数据报转化成字符串显示
            //起始位置,长度,编码方式
            String response = new String(responsePacket.getData(),0,responsePacket.getLength(),"UTF-8");
            //输出响应
            System.out.println("req:"+request+" res:"+response);
        }
    }

    public static void main(String[] args) throws IOException {
        //这里传入的是服务器的IP和端口号
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);
        //启动服务器
        udpEchoClient.start();
    }
}

启动服务器:
在这里插入图片描述
启动客户端:
在这里插入图片描述
我们需要先启动服务器,然后再启动客户端,因为服务器是被动接收的一方,如果客户端没有和服务器发送信息,那么服务器就会一直阻塞在socket.receive(requestPacket)等待客户端!
在这里插入图片描述
服务器接收到端口号为57266客户端的请求,发送了响应!
在这里插入图片描述
而客户端也接收到了服务器发送的响应,实现了回显服务!

我们知道一个服务器程序一般都有多个客户端访问!
如果想要有其他的客户端访问,该如何做呢!
在这里插入图片描述
当我们再次启动客户端程序,会弹出让我们先关闭该程序的窗口!
这样就只能运行一个客户端…

当我们Allow parallel run就可以同时运行多个实例!
在这里插入图片描述
在这里插入图片描述
此时我们就有多个客户端了!
在这里插入图片描述
服务器也连接了多个客户端!
这就是实现了1对多!

  • 字典服务客户端服务器

刚刚的案例,显然没有一点技术,我可改进一下响应,写一个字典服务的服务器,支持中英翻译!

//翻译服务服务器
import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
public class UdpDictServer extends UdpEchoServer{
    private HashMap<String,String> dict = new HashMap<>();
    public UdpDictServer(int port) throws SocketException {
        super(port);
        dict.put("cat","小猫");
        dict.put("dog","小狗");
        dict.put("pig","小猪");
        dict.put("child","小孩");
    }
    @Override
    public String process(String request) {
        //返回翻译!
        return dict.getOrDefault(request,"暂且不会");
    }

    public static void main(String[] args) throws IOException {
        UdpDictServer udpDictServer =new UdpDictServer(9090);
        udpDictServer.start();
    }
}

我们客户端并不用改变,访问该服务器就可以实现翻译的效果!
在这里插入图片描述

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。