模拟回显服务器

1.了解什么是回显

回显指当本地终端向远端设备发送数据时,远端设备将接收到的数据再发送回本地终端显示出来的过程。比如我们在命令行中输入一些指令后,服务器返回的相关信息显示在命令行界面上,这就是一种回显情况,像用"ping"命令去测试网络连通性时,返回的如IP地址、响应时间等信息的显示就是回显的体现。

2.基于UDP实现回显服务器需要使用的方法

1.DatagramSocket,可以这么理解,这就是一个电话,用来接收和发送信息的

receive方法用来接收信息

send方法用来发送信息的

close方法,你信息发完了,不使用就需要进行关机
2.DatagramPacket,就是你的电话发送的信息,这个信息就像快递一样,打包一起发过去,他也有一个名字叫做数据报,对于客户端来说,我们在将这个快递"寄"出去时,需要填写对方的IP地址和端口号,来指定寄给谁,然而对方(也就是服务器)不需要知道我们的地址,因为,我们将这个快递寄出去时,快递上就写了我们(客服端)的地址和端口号

服务器获取数据报的地址和端口号:数据报名.getSocketAddress()

3.代码解析与实现

服务端代码:

package notwork;

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

public class UdpEchoSever_3 {
     DatagramSocket socket=null;
//给服务器搞一个"电话",让他可以使用这个电话来接收和发送信息
    public UdpEchoSever_3(int port) throws SocketException {
       socket=new DatagramSocket(port);
       //指定一个端口让服务器来使用
    }

    public void start() throws IOException {
        //打印个信息,表示服务器启动
        System.out.println("服务器启动");

        /**
         * 循环一次代表处理一次请求,也就是对方发个问题过来,你给他解决,
         *
         * 然而处理请求的过程一般分为三步
         * 1.读取请求并解析
         * 2.根据请求,计算响应(服务器最为关键的一步)
         * 3.把响应返回给客户端
         **/

        while(true){
            //1.读取请求并解析
            //   DatagramPacket 表示一个数据报,此处传入的字节数组,就保存UDP的载荷部分。
            DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);
           //接收客户端发来的数据报
            socket.receive(requestPacket);
            //把读取到的二进制数据,转换成字符串,只是构造有效的部分
            String request=new String(requestPacket.getData(),0, requestPacket.getLength());

            //2.根据请求,计算响应
            //我们此处写的是回显服务器
            //所以意思意思,写个计算响应的方法,将请求原封不动的返回一下
            String reponse=process(request);

            //3.把响应返回给客户端
            //将字符串转化为字节数组,然后获取字节数组的长度,并使用接收的数据报获取客户端的IP地址和端口号
            DatagramPacket reponsePacket=new DatagramPacket(reponse.getBytes(),reponse.getBytes().length, requestPacket.getSocketAddress());
           //将响应的数据报发送给客户端
            socket.send(reponsePacket);
            //打印一下日志
            System.out.printf("[%s:%d]  rqs:%s   rep:%s",requestPacket.getAddress(),requestPacket.getPort(),request,reponse);
        }

    }


    //后续写其他服务器时,只需要修改一下计算响应的这个方法就行了
    //可以继承这个类,然后重写process方法,将private修改为public就行
    private String process(String request) {
    return request;
    }

    public static void main(String[] args) throws IOException {
     UdpEchoSever_3 sever_3=new UdpEchoSever_3(4565);
        sever_3.start();
    }
}

客户端代码:

package notwork;

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

public class UdpEchoClient_3 {
    private String IpSever;
    private int portSever;
    private DatagramSocket socket=null;

    //和服务器不同,客户端是要先发出请求,所以第一个数据报是从客户端发出,需要知道服务器的IP地址和端口号
    public UdpEchoClient_3(String ipSever, int portSever) throws SocketException {
        this.IpSever = ipSever;
        this.portSever = portSever;
        socket=new DatagramSocket();
    }

    public void start() throws IOException {
        Scanner scanner=new Scanner(System.in);

        while(true){
//1.从控制台读取用户输入的信息
            System.out.printf("请输入请求:");
            if(!scanner.hasNext()){
                break;
            }
            String request= scanner.next();
            //2.把请求发送给服务器,构造一个数据报,将字符串转化为字节数组,加上字节数组的长度,以及将IP地址从字符串转化为指定的类型,加上端口号
            DatagramPacket requestPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(IpSever),portSever);
            //将数据报发送给服务器
            socket.send(requestPacket);

            //创建一个数据报对象用来接收服务器返回的数据报
            DatagramPacket reponsePacket=new DatagramPacket(new byte[4096],4096);
            //接收数据报
            socket.receive(reponsePacket);
            //将数据报的信息转化为字符串
            String reponse=new String(reponsePacket.getData(),0,requestPacket.getLength());
            //将响应的信息打印
            System.out.println(reponse);
        }
    }

    public static void main(String[] args) throws IOException {
        //127.0.0.1通常被称为回环IP,可以将服务器和客户端在一台电脑上运行
     UdpEchoClient_3 client_3=new UdpEchoClient_3("127.0.0.1",4565);
     client_3.start();
    }
}
相关推荐
想学习java初学者17 分钟前
Docker compose部署elasticsearch(单机版)
运维·docker·容器
落落落sss24 分钟前
MQ集群
java·服务器·开发语言·后端·elasticsearch·adb·ruby
我救我自己24 分钟前
UE5运行时创建slate窗口
java·服务器·ue5
人类群星闪耀时44 分钟前
未来运维的发展趋势:运维领域的新技术与趋势
运维
落非1 小时前
NFS存储基础操作
运维
Vanish_ran1 小时前
gitlab与jenkins
运维·gitlab·jenkins
大风吹PP凉1 小时前
38配置管理工具(如Ansible、Puppet、Chef)
linux·运维·服务器·ansible·puppet
康熙38bdc2 小时前
Linux 进程间通信——共享内存
linux·运维·服务器
刘艳兵的学习博客2 小时前
刘艳兵-DBA033-如下那种应用场景符合Oracle ROWID存储规则?
服务器·数据库·oracle·面试·刘艳兵
微刻时光2 小时前
Docker部署Nginx
运维·nginx·docker·容器·经验