基于udp实现回显服务器,翻译服务器

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

udp socket 要掌握的类:

1.DatagramSocket

2.DatagramPacket

一、udp版本回显服务器

服务端:

完整代码

客户端:

完整代码

udp版本翻译服务器:

 代码:





udp socket 要掌握的类:

1.DatagramSocket

是UDP Socket,用于发送和接收UDP数据报。(网卡的代言人)

构造方法:
基于udp实现回显服务器,翻译服务器_第1张图片

 第一种一般用于客户端,第二种一般用于服务器

其他方法:

基于udp实现回显服务器,翻译服务器_第2张图片

 总结:socket本质上也是文件

socket对应到网卡这个硬件设备,操作系统也是把网卡当做文件来管理的

通过网卡发送数据写文件

通过网卡接受数据读文件

文件操作要先打开文件,然后读文件,最后关闭对应到socket上,构造方法相当于打开,receive,send相当于写,close相当于关闭

2.DatagramPacket

代表一个udp数据报,也就是一次发送接受的基本单位

构造方法

基于udp实现回显服务器,翻译服务器_第3张图片

其他方法:

基于udp实现回显服务器,翻译服务器_第4张图片

一、udp版本回显服务器

服务端:

1.绑定端口:

基于udp实现回显服务器,翻译服务器_第5张图片

一个端口只能绑定一个进程

2.启动服务器:

基于udp实现回显服务器,翻译服务器_第6张图片

 3.接受命令:

基于udp实现回显服务器,翻译服务器_第7张图片

4.处理响应:

5..响应写会客户端
 

基于udp实现回显服务器,翻译服务器_第8张图片

InetSocketAddress(getAddress(), getPort());

 6.打印日志

完整代码

package net_1011;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class UdpEchnoServer {
        private DatagramSocket socket=null;
        //参数的端口表示咱的服务器要绑定的端口
        public UdpEchnoServer(int port) throws SocketException {
            socket=new DatagramSocket(port);
        }
        //通过这个方法启动服务器
        public void start()throws IOException{
            System.out.println("服务器启动!");
            while(true){
                //循环里面处理一次请求
                //读取请求并解析
                DatagramPacket requestPacket=new DatagramPacket(new byte[4096],4096);
                socket.receive(requestPacket);
                //把这个DatagramPacket对象转变成字符串,方便去打印
                String request=new String(requestPacket.getData(),0,requestPacket.getLength());
                //2.根据请求计算相应
                String response =process(request);
                //3.把相应写回到客户端
                DatagramPacket responsePacket=new DatagramPacket(response.getBytes(),response.getBytes().length,
                        requestPacket.getSocketAddress());
                socket.send(requestPacket);
                //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 {
            UdpEchnoServer server=new UdpEchnoServer(9090);
            server.start();
        }
    }

客户端:

1.绑定端口(注意区别)Ip+端口

基于udp实现回显服务器,翻译服务器_第9张图片

 服务器的ip一般都是本机ip不需要绑定,当涉及多个网卡,多个Ip,访问指定ip地址,服务器才要手动指定ip

2.注意构造方法没有指定参数

基于udp实现回显服务器,翻译服务器_第10张图片

//这里并不是说没有端口,而是让系统自动指定一个空闲的端口

系统分配的空闲端口,避免用户乱输入端口,导致影响到进程运行中的端口,

3.注意构造出的数据报是以字节为单位

基于udp实现回显服务器,翻译服务器_第11张图片

 4.关于DatagramPacket构造的几种方式:

基于udp实现回显服务器,翻译服务器_第12张图片

完整代码

package net_1011;

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

public class UdpEchoClient {
    private DatagramSocket socket=null;
    private String serverIP;
    private int serverPort;
    //俩个参数一会会在发送数据的时候用到
    //暂时先把这俩参数存起来,以备后用
    public UdpEchoClient(String serverIP,int serverPort) throws SocketException {
        //这里并不是说没有端口,而是让系统自动指定一个空闲的端口
        socket=new DatagramSocket();
        //假设 serverIP 是形如 1.2.3.4 这种点分十进制的表示方式
        this.serverIP=serverIP;
        this.serverPort=serverPort;
    }
    public void start() throws IOException {
        Scanner scanner=new Scanner(System.in);
        while(true){
            //1.从控制台读取用户输入的内容
            System.out.println("-> ");
            String request=scanner.next();
            //2.构造一个udp请求,发送给服务器
            DatagramPacket requstPacket=new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(this.serverIP),this.serverPort);
            socket.send(requstPacket);
            //3.从服务器中读取udp响应数据,并解析
            DatagramPacket responsePacket=new DatagramPacket(new byte[4096],4096);
            socket.receive(requstPacket);
            String response=new String(responsePacket.getData(),0,responsePacket.getLength());
            //4.把服务器的响应显示到控制台上
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient client=new UdpEchoClient("127.0.0.1",9090);
        client.start();
    }
}

 总的执行流程:

基于udp实现回显服务器,翻译服务器_第13张图片

直观表示:

基于udp实现回显服务器,翻译服务器_第14张图片

 怎样处理多个请求:

对于服务器来说

读取请求并接续,根据请求并计算相应,把响应写会到客户端执行速度极快,这时候如果有多个客户端发来请求,服务器也是可以响应的在服务器上本质是三个请求串行处理的

如果处理不过来,采用分布式

udp版本翻译服务器:

基于udp实现回显服务器,翻译服务器_第15张图片

 代码:

package net_1011;

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

public class UdpTranslateServer extends UdpEchnoServer{
    //翻译是啥?本质上就是 key ->value
    private Mapdict=new HashMap<>();
    public UdpTranslateServer(int port) throws SocketException {
        super(port);
        dict.put("cat","小猫");
        dict.put("dog","小狗");
        dict.put("fuck","卧槽");
        //在这里就可以填入很多很多内容,像有道词典程序就这样
    }

    //重写process 方法,实现查询哈希表的操作
    @Override
    public String process(String request){
        return dict.getOrDefault(request,"词在词典中未找到");
    }

    //start方法和父类完全一样,不用写了
    public static void main(String[]args) throws IOException{
        UdpTranslateServer server=new UdpTranslateServer(9090);
        server.start();
    }
}

你可能感兴趣的:(网络初始,udp,python,网络协议)