【JavaEE】_基于UDP实现网络通信

这篇具有很好参考价值的文章主要介绍了【JavaEE】_基于UDP实现网络通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. 服务器

1.1 实现逻辑

1.2 代码

1.3 部分代码解释

2. 客户端

2.1 实现逻辑

2.2 代码

2.3 客户端部分代码解释

3. 程序运行结果

4. 服务器客户端交互逻辑


1. 实现UDP版本的回显服务器echo server

普通服务器:收到请求,根据请求计算响应,返回响应;

回显服务器:忽略计算,直接将收到的请求作为响应返回;

如需实现其他功能,修改响应计算方法process内容即可);

具体实现代码如下:

1.1 服务器UDPEchoServer

1.1.1 实现逻辑

对于网络通信的服务器需要进行的工作为:

1. 读取请求并解析;

2. 根据请求计算响应;

3. 把响应写回客户端;

4. 打印交互详细信息;

1.1.2 代码

package TestDemo1;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UDPEchoServer {
    // 创建一个DatagramSocket对象,作为后续操作网卡的基础
     private DatagramSocket socket = null;
     public UDPEchoServer(int port) throws SocketException{
         // 显式指定服务器端口号
         socket = new DatagramSocket(port);
     }
     public void start() throws IOException {
         // 服务器启动方法
         System.out.println("服务器启动");
         // 为保证服务器随时向客户端提供服务
         while(true){
             // 1. 读取请求并解析
             DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
             // DatagramPacket对象用于承载从网卡读到的数据,收到数据时需要创建一个内存空间保存这个数据,
             // DatagramPacket内部不能自行分配内存空间,需要程序员手动创建
             socket.receive(requestPacket);
             // 完成receive之后,数据以二进制形式存储在DatagramPacket中
             // 需要将二进制数据转成字符串
             String request = new String(requestPacket.getData(),0, requestPacket.getLength());
             // 取0~requestPacket.getLength()区间内的字节构成一个String对象;

             //2. 根据请求计算响应
             String response = process(request);

             //3. 把响应写回客户端
             DatagramPacket responsePacket = new DatagramPacket(
                     response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
             socket.send(responsePacket);

             //4. 打印交互详细信息
             System.out.printf("[%s:%d] req=%s, resp=%s\n",
                     requestPacket.getAddress().toString(),requestPacket.getPort(),
                     request,response);
         }
     }
     public String process(String request){
         return request;
     }

    public static void main(String[] args) throws IOException {
        UDPEchoServer server = new UDPEchoServer(9090);
        // 可以在1024~65535(临时端口)中任意选取端口号
        server.start();
    }
}

1.1.3 部分代码解释

1. 为方便计算请求,将请求的DatagramPacket对象构造成字符串时只需获取DatagramPacket对象中实际有效的部分数据,requestPacket.getLength()获取到的就是收到数据的真实长度而非4096这个最大长度:

【JavaEE】_基于UDP实现网络通信,JavaEE,java-ee,udp,java

2. 已经了解过UDP本身是无连接的,故而对于每一次通信过程,在构造数据报时都需要指定数据报要发给谁;

(1)对于构造的responsePacket对象有3个参数:

DatagramPacket responsePacket = new DatagramPacket(                   
response.getBytes(),
response.getBytes().length,
requestPacket.getSocketAddress());

response.length()获取到的是响应对象字符串的字符个数,

response.getBytes().length获取到的是响应对象字符串的字节个数;

requestPacket.getSocketAddress()获取到的是请求发送方(即客户端)的IP与端口号

(2)注意response.getBytes.length(字节个数)与response.getlength()(字符个数)的区别:

如果response字符串都是英文字符则二者相等,如果包含中文则二者不同;

在进行网络传输时,必然是需要通过字节为单位进行通信的。

3. while(true)会使程序处于快速循环的状态,每循环一次就处理一次请求响应,

当客户端发出请求时,recerive就能顺利读取请求,客户端没有发出请求时,receive就会阻塞

如果客户端发出的请求过多,可以使用多线程冲动调动计算机硬件资源,也可以再多开机器,但多开机器又会涉及到分布式问题;

4. 使用格式化输出Packet的IP与端口号:

【JavaEE】_基于UDP实现网络通信,JavaEE,java-ee,udp,java

5. 前文已经提及socket也是一个文件,但在上文代码中并未进行close操作,却没有造成文件资源泄漏的原因是:

socket是文件描述符表中的一个表项,每次打开一个文件就会占用一个位置,文件描述符在pcb上,是跟随进程的。在上文代码中创建的socket对象在整个程序运行过程中都需要使用,不可以提前关闭,当socket不需要使用时,即代表程序结束了,进程结束了,文件描述符表也销毁了,伴随着销毁都被系统自动回收了。故而不会造成文件资源泄露问题

只有代码中频繁打开文件但不关闭,在一个进程的运行过程中,不断积累打开的文件,逐渐消耗掉文件描述符表中的内容,最后消耗殆尽,才会造成泄露。

对于生命周期很短的进程,无需考虑泄露,在客户端方一般来说影响不大。

1.2客户端UDPEchoClient

1.2.1 实现逻辑

对于网络通信的客户端,需要进行的工作是:

1. 从控制台读取数据作为客户端发出的请求;

2. 将请求字符串request构造成请求requestPacket对象,发送给服务器;

3. 尝试读取服务器返回的响应;

4. 将响应responsePacket对象构造成响应response字符串,显示出来;

1.2.2 代码

package TestDemo1;

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

public class UDPEchoClient {
    private DatagramSocket socket = null;
    private String serverIp = "";
    private int serverPort = 0;
    public UDPEchoClient(String ip, int port) throws SocketException {
        // 客户端的socket对象需令系统自动分配
        socket = new DatagramSocket();
        // UDP本身不持有对端信息,需要在应用程序中记录对端信息(IP与端口)
        serverIp = ip;
        serverPort = port;
    }
    public void start() throws IOException {
        // 客户端启动方法
        System.out.println("客户端启动");
        Scanner scanner = new Scanner(System.in);
        while(true){
            // 1. 从控制台读取数据作为客户端发出的请求
            System.out.println("->");
            String request = scanner.next();

            // 2. 将请求字符串request构造成请求requestPacket对象,发送给服务器
            DatagramPacket requestPacket = new DatagramPacket(
                    request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(serverIp), serverPort);
            socket.send(requestPacket);

            // 3. 尝试读取服务器返回的响应
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);

            // 4. 将响应responsePacket对象转换为响应字符串response,显示出来
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            System.out.println(response);
        }
    }
    public static void main(String[] args) throws IOException {
        UDPEchoClient client = new UDPEchoClient("127.0.0.1", 9090);
        client.start();
    }
}

1.2.3 客户端部分代码解释

1.DatagramPacket的三个构造方法

第一种:只指定字节数组缓冲区,用于服务器接收请求与客户端接收响应时使用

【JavaEE】_基于UDP实现网络通信,JavaEE,java-ee,udp,java

第二种:指定字节数组缓冲区与InetAddress对象(同时包含IP与端口),用于服务器向客户端发回响应时使用

【JavaEE】_基于UDP实现网络通信,JavaEE,java-ee,udp,java

第三种:指定字节数组缓冲区,同时指定IP与端口号

【JavaEE】_基于UDP实现网络通信,JavaEE,java-ee,udp,java

2. 客户端对服务器发出请求的过程:

对于服务器端口必须是确定的:程序员可以手动分配空闲端口给当前服务器使用即可,

代码为:

socket = new DatagramSocket(port);

【JavaEE】_基于UDP实现网络通信,JavaEE,java-ee,udp,java

客户端一般都采取系统分配的方式:也可以指定端口,但不推荐。一方面,因为指定的端口可能被其他进程占用,如果被占用就会产生端口号冲突,运行就会抛出异常,提示绑定端口失败;另一方面,如果客户端出现了端口冲突,让客户手动解决也是不现实的。

代码为:

socket = new Datagramocket();

3. 端口与进程的关系:

端口号用于标识或区分一个进程,因此在同一台主机上,不允许一个端口同时被多个进程使用;

但是一个进程可以绑定多个端口;

socket和端口是一一对应的,进程与socket是一对多的

1.3 程序运行结果

首先启动EchoServer,再启动EchoClient,在客户端输入请求字符串后查看运行结果:

【JavaEE】_基于UDP实现网络通信,JavaEE,java-ee,udp,java

【JavaEE】_基于UDP实现网络通信,JavaEE,java-ee,udp,java

客户端与服务器通信成功。

1.4 服务器客户端交互逻辑

1. 服务器先启动,启动后进入循环,执行到receive处阻塞;

2. 客户端开始启动后,进入循环执行scanner.next(),在此处阻塞。

    当客户在控制台输入内容后,next返回作为请求,继而构造请求数据并发送给服务器;

3. 客户端发送数据后,

服务器从receive中返回,解析请求构造字符串,执行process操作计算响应,构造响应后执行send发回给客户端;

客户端执行到receive处等待服务器的响应;

4. 客户端获取到从服务器返回的数据后,从receive中返回,继而显示响应内容;

5. 服务器完成一次循环后又执行到receive处,客户端完成依次循环后又执行到scanner.next处,二者均进入阻塞状态;

注意:当服务器程序在普通私有ip计算机上运行时,若不在一个局域网中,无法实现跨主机访问。

如果服务器程序在特殊的计算机:云服务器上,就拥有了公有ip,可以实现跨主机访问。

此部分内容后续详解。

2. 实现UDP版本的翻译服务器

方法1:复制上文实现的回显服务器与客户端程序,仅修改服务器的process方法即可;

方法2:复用上文回显服务器与客户端代码,使用继承与多态;

此处以方法2为例。

2.1 服务器UDPDictServer

package TestDemo1;

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

public class UDPDictServer extends UDPEchoServer{
    private Map<String, String> dict = new HashMap<>();
    public UDPDictServer(int port) throws SocketException {
        super(port);
        // 可在该表中插入成千上万个键值对
        dict.put("dog", "小狗");
        dict.put("cat", "小猫");
        dict.put("pig", "小猪");
    }
    // 重写process方法完成翻译过程
    @Override
    public String process(String request){
        return dict.getOrDefault(request, "该词在词典中不存在");
    }

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

注:1. 子类的引用调用start方法,在start方法中又调用process方法,隐藏在start方法中的this指向子类引用,故而调用的是重写后的process方法;

若继承多态部分尚有疑问,请移步JavaSE专栏继承多态一篇,链接如下:

【JavaSE】_6.继承与多态_java继承与多态-CSDN博客

2.2 客户端

可直接使用上文的UDPEchoClient;

2.3 程序运行结果

【JavaEE】_基于UDP实现网络通信,JavaEE,java-ee,udp,java

客户端服务器通信成功。文章来源地址https://www.toymoban.com/news/detail-811414.html

到了这里,关于【JavaEE】_基于UDP实现网络通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【QT网络编程】实现UDP协议通信

    Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了 一种无需建立连接就可以发送封装的 IP 数据包的方法 。RFC 768 描述了 UDP。 UDP协议根据消息传送模式可以分为: 单播(Unicast)、组播(Multicast)和广播(

    2024年02月02日
    浏览(56)
  • FPGA基于SFP光口实现10G万兆网UDP通信 10G Ethernet Subsystem替代网络PHY芯片 提供工程源码和技术支持

    目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中不会用这样的代码,试想,多机互联,出现了问题,你的网卡都不带ping功能,连基本的问题排查机制都不具备,这样的代

    2024年02月01日
    浏览(51)
  • Linux之套接字UDP实现网络通信

    ​ 套接字(Socket)是计算机网络中实现网络通信的一种 编程接口 。它提供了应用程序与网络通信之间的一座桥梁,因为它允许应用程序通过网络发送和接收相应的数据以实现不同主机之间的通信。 ​ 通常套接字由以下两部分组成: 1.网络IP和端口号 :IP用来标识主机,而端口

    2024年02月11日
    浏览(45)
  • 使用 python socket 实现UDP/TCP网络通信

    目录 目录 1.socket简介 2.创建socket 2.1创建UDPSocket 2.2创建TCPSocket 3.使用UDPSocket发送数据并接收 4.使用UDPSocket发送广播 5.UDPSocket聊天器 (多线程实现消息的收发功能) 6.使用TCPSocket建立客户端 7.使用TCPSocket建立服务端        socket(简称:套接字),是支持TCP和UDP(网络传输方式

    2023年04月10日
    浏览(65)
  • 【网络编程】利用套接字实现一个简单的网络通信(UDP实现聊天室 附上源码)

    源IP地址(Source IP Address): 源IP地址是数据包发送方(或数据流出发点)的唯一标识符。它用于在互联网或本地网络中定位发送数据包的设备或主机。源IP地址是数据包的出发点,即数据从这个地址开始传送,向目的IP地址指示的设备发送。 在TCP/IP协议中,源IP地址通常由发

    2024年02月14日
    浏览(86)
  • FPGA基于SFP光口实现千兆网UDP通信 1G/2.5G Ethernet PCS/PMA or SGMII替代网络PHY芯片 提供工程源码和技术支持

    目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中不会用这样的代码,试想,多机互联,出现了问题,你的网卡都不带ping功能,连基本的问题排查机制都不具备,这样的代

    2024年02月08日
    浏览(66)
  • FPGA基于SFP光口实现1G千兆网UDP通信 1G/2.5G Ethernet PCS/PMA or SGMII替代网络PHY芯片 提供工程源码和技术支持

    目前网上的fpga实现udp基本生态如下: 1:verilog编写的udp收发器,但不带ping功能,这样的代码功能正常也能用,但不带ping功能基本就是废物,在实际项目中不会用这样的代码,试想,多机互联,出现了问题,你的网卡都不带ping功能,连基本的问题排查机制都不具备,这样的代

    2024年02月08日
    浏览(49)
  • 【JAVAEE】网络原理之网络通信基础

    目录 1. 💋IP地址 1.1 🍟IP地址的格式 1.2 🎁特殊IP地址 2. ✨端口号 2.1  🎃端口号的格式 3. 😘网络协议 3.1 🎨为什么需要网络协议? 3.2 💛网络协议的概念与组成 3.3 🍉知名协议的默认端口 3.4 🐷五元组 4. 🍳网络协议分层 4.1 🍭协议分层的好处 4.2 🎩网络协议的分层模型一

    2023年04月24日
    浏览(42)
  • [JAVAee]网络通信基础

    目录 IP地址 端口号 网络协议 五元组 TCP/IP五层模型 网络互连之间的目的就是为了相互通信,传输数据,是可以不同进程间的基于网络的数据传输. 而IP就可以确定网络通信的双方.  IP地址主要用于定位标识网络主机或其他网络设备的网络地址 .(就像快递的收货地址一般) 格式:

    2024年02月14日
    浏览(42)
  • 【JavaEE】_网络通信原理

    目录 1. 网络发展史 2. 网络通信基础 1.1 IP地址 1.2 端口号 1.3 协议 1.3.1 概念 1.3.2 五元组 1.4  协议分层 1.4.1 协议分层的优点 1.4.2 协议分层的分类 1.4.3网络设备所在分层 1.4.4 两台主机通过TCP/IP协议通讯过程 1.5 封装与分用 1.5.1 封装 1.5.2 分用 (1)单机:计算机之间相互独立;

    2024年01月19日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包