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

 udp回显服务器

package network;

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

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ZN
 * Date: 2023-03-24
 * Time: 18:54
 */

//Udp协议服务器
public class UdpEchoSever {
    // 网络编程, 本质上是要操作网卡.
    // 但是网卡不方便直接操作. 在操作系统内核中, 使用了一种特殊的叫做 "socket" 这样的文件来抽象表示网卡.
    // 因此进行网络通信, 势必需要先有一个 socket 对象.
    private DatagramSocket socket = null;

    //创建socket一定要绑定一个指定的端口号
    //服务器在网络传输上是被动的一方,如果不指定一个端口号
    //那么系统就会随机分配一个端口号,客户端就不能与服务器进行网络传输
    public UdpEchoSever(int port) throws SocketException {
        socket = new DatagramSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动");
        // 服务器不是只给一个客户端提供服务就完了. 需要服务很多客户端.
        while (true) {
            // 只要有客户端过来, 就可以提供服务.
            // 1. 读取客户端发来的请求是啥.
            //    receive 方法的参数是一个输出型参数, 需要先构造好个空白的 DatagramPacket 对象. 交给 receive 来进行填充.
            DatagramPacket requestPacket = new DatagramPacket(new byte[4090],4090);//长度最长可以是4090
            socket.receive(requestPacket);
            // 此时这个 DatagramPacket 是一个特殊的对象, 并不方便直接进行处理. 可以把这里包含的数据拿出来, 构造成一个字符串.
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());
            // 2. 根据请求计算响应, 由于此处是回显服务器, 响应和请求相同.
            String response = process(request);
            // 3. 把响应写回到客户端. send 的参数也是 DatagramPacket. 需要把这个 Packet 对象构造好.
            //    此处构造的响应对象, 不能是用空的字节数组构造了, 而是要使用响应数据来构造.
            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);
        }
    }
    // 这个方法就表示 "根据请求计算响应"
    private String process(String request) {
        return request;
    }
    public static void main(String[] args) throws IOException {
        // 端口号的指定, 大家可以随便指定.
        // 1024 -> 65535 这个范围里随便挑个数字就行了.
        UdpEchoSever udpEchoSever = new UdpEchoSever(9090);
        udpEchoSever.start();
    }
}

udp回显客户端

package network;

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

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: ZN
 * Date: 2023-03-24
 * Time: 19:27
 */
public class UdpEchoClient {
    // 一次通信, 需要有两个 ip, 两个端口.
    // 客户端的 ip 是 127.0.0.1 已知.
    // 客户端的 port 是系统自动分配的.
    // 服务器 ip 和 端口 也需要告诉客户端. 才能顺利把消息发个服务器
    DatagramSocket socket = null;
    private String severIp = null;
    private int serverPort = 0;
    public UdpEchoClient(String severIp,int serverPort) throws SocketException {
        socket = new DatagramSocket();
        this.serverPort = serverPort;
        this.severIp = severIp;
    }

    public void start() throws IOException {
        System.out.println("客户端启动");
        // 1. 从控制台读取要发送的数据
        Scanner scanner = new Scanner(System.in);
        while(true){
            System.out.print("> ");
            String request = scanner.next();
            if (request.equals("exit")) {
                System.out.println("goodbye");
                break;
            }
            // 2. 构造成 UDP 请求, 并发送
            //    构造这个 Packet 的时候, 需要把 serverIp 和 port 都传入过来. 但是此处 IP 地址需要填写的是一个 32位的整数形式.
            //    上述的 IP 地址是一个字符串. 需要使用 InetAddress.getByName 来进行一个转换.
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(severIp),serverPort);
            socket.send(requestPacket);
            // 3. 读取服务器的 UDP 响应, 并解析
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);
            String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
            // 4. 把解析好的结果显示出来.
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        //下面的ip可以换成云服务器的ip,这样就可以在云服务器上进行网络传输
        //127.0.0.1是本地IP地址
        UdpEchoClient udpEchoClient = new UdpEchoClient("127.0.0.1",9090);
        udpEchoClient.start();
    }
}

因为服务器是被动的接受客户端发来的请求,服务器无法确定客户端何时发来请求,所以服务器就一定要一直保持启动,所以运行代码时要先执行服务器,后执行客户端。

下面是代码运行结果

Udp回显服务器和回显客户端_第1张图片

 Udp回显服务器和回显客户端_第2张图片

 基于udp回显服务器和客户端,我们就可以进一步实现udp版本的查字典服务器和客户端

后续我会发布,希望点点关注。

你可能感兴趣的:(java-ee,服务器,udp,java)