UDP实现客户端服务器网络编程

Author:老九
计算机专业
可控之事 沉重冷静 不可控之事 乐观面对
[email protected]
☺️

❓ ❤️ ☕️ ❗️
————————————————
版权声明:本文为CSDN博主「浦上青天」的原创文章

文章目录

  • IP地址 / 端口号
  • 通信的五元组
  • Socket API编程接口
    • 使用简答的UDP网络实现回显服务器(echo server)
  • 客户端代码
  • 客户端跨主机通信过程
    • 用idea打jar包:
  • 体会客户端服务器的基本工作流程
  • 实践翻译服务器(简单的英译汉)

知识点

IP地址 / 端口号

  • IP地址:用来识别互联网上一台主机的位置
  • 端口号:用来区分一台主机上的哪个应用程序

通信的五元组

  • 源IP:发件人的地址
  • 源端口 :发件人姓名
  • 目的IP:收件人地址
  • 目的端口:收件人姓名
  • 协议类型

端口号是传输层协议的内容,0-65535的一个整数(占两个字节)
IP地址是一个32位的整数,“点分十进制”
端口号用来标识一个进程,告诉操作系统,当前的这个数据要交给哪一个进程来处理
IP地址+端口号能够标识网络上某一台主机的某一个进程
一个端口号只能被一个进程占用
服务器程序必须关联一个固定的端口号,MySQL默认3306

Socket API编程接口

  • SocketAPI(本质是一个文件,网卡的抽象)
  • Java标准库中提供了两种风格:
  • 1.UDPDatagramSocket:面向数据报(发送接受数据,必须以一定的数据包为单位进行传输)
  • 2.TCPServerSocket:面向字节流
    这两个是传输层中最重要的两个协议

使用简答的UDP网络实现回显服务器(echo server)

  • List item
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * Description:
 * User: 李明浦
 * Date: 2022-02-07
 * Time: 9:19
 */
public class UDPEchoServer {
    //对于一个服务器程序来说,核心流程也要分成两步
    //1.进行初始化操作(实例化 socket对象)
    //2.进入主循环,接受并处理请求(主循环就是一个“死循环”)
    //   a)读取数据并解析
    //   b)根据请求计算响应
    //   c)把响应结果写回客户端

    //需要一个UDP的连接
    private DatagramSocket socket = null;
    //在构造函数里初始化操作实现连接,并指定端口号
    public UDPEchoServer(int port) throws SocketException {
        //服务器new socket对象的时候需要和一个ip地址和端口号绑定起来
        //如果没有写ip,则默认0.0.0.0(这是一个特殊的ip会关联到这个主机的所有网卡的ip)
        //socket对象本身就是一个文件,这个文件就是网卡的抽象
        socket = new DatagramSocket(port);
    }

    public void start() throws IOException {
        System.out.println("服务器启动");
        while(true)
        {
            //a)读取请求并解析
            //括号里是一个接受数据的缓冲区,需要用户自己手动提供,地址是在接受数据的时候由内存填充
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            //程序启动会很快到达receive操作,如果客户端没有发送任何数据,此时receive操作会阻塞
            //一直到有客户端发送数据过来,当有客户端发送数据过来时候,receive就会将数据保存到DategramPacket对象的缓冲区中
            socket.receive(requestPacket);
            //把原本请求的数据时byte[]将其转化为String,并且如果发来的数据小于我们缓冲区的大小就会默认添加空格,我们需要去掉无用的空格
            String request = new String(requestPacket.getData(),0, requestPacket.getLength()).trim();
            //b)根据请求计算响应,处理请求
            String response = process(request);
            //c)把响应写回给客户端,响应数据就是response,需要包装成一个Packet对象
            //这个packet对象要发给谁(目的IP和端口是谁),这两个信息就包含在requestPacket内部了,在调用
            //getSocketAddress()方法,就可以获取目的IP和端口了
            //response.length()得到的是字符数量,而我们需要的是字节数
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
            socket.send(responsePacket);

            //打印一条请求日志
            System.out.printf("[%s:%d] req: %s; resp: %s\n",requestPacket.getAddress().toString()
            ,requestPacket.getPort(),request,response);
        }
    }

    private String process(String request) {
        //由于此处是一个echo server,请求内容是啥,响应内容就是啥
        //如果是一个更复杂的服务器,此处就需要包含很多的业务逻辑和具体的计算
        return request;
    }

    public static void main(String[] args) throws IOException {
        //一个主函数去设置该服务器的端口,并让其开始执行
        UDPEchoServer server = new UDPEchoServer(9090);
        server.start();
    }
}

客户端代码

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

/**
 * Description:
 * User: 李明浦
 * Date: 2022-02-07
 * Time: 12:57
 */
public class UDPEchoClient {
    //客户端的主要流程分成四步
    //1.从用户这里读取输入的数据
    //2.构造请求发送给服务器
    //3.从服务器读取相应
    //4.把响应写回给客户端

    private DatagramSocket socket =null;
    private String serverIp = null;
    private  int serverPort = 0;
    //启动客户端的时候,指定需要连接哪个服务器
    public UDPEchoClient(String serverIp,int serverPort) throws SocketException {
        this.serverIp = serverIp;
        this.serverPort = serverPort;
        //客户端中,创建socket的时候,不需要绑定端口号,由操作系统自动分配一个空闲端口
        //一个端口号只能被一个进程绑定
        //服务器绑定了端口之后,客户端才能访问
        //其次如果客户端绑定了的话,一个主机就只能启动一个客户端了
        socket = new DatagramSocket();

    }

    public void start() throws IOException {
        Scanner scanner = new Scanner(System.in);
        while(true)
        {
            //1.读取用户输入数据
            System.out.println("输入字符串->");
            String request = scanner.nextLine();
            if(request.equals("exit"))
            {
                break;
            }
            //2.构造请求,发送给服务器
            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(requestPacket);
            String response = new String(requestPacket.getData(),0
                    ,requestPacket.getLength()).trim();
            //4.显示响应数据
            System.out.println(response);
        }
    }

    public static void main(String[] args) throws IOException {
        //此时我们用于自己主机实验,127.0.0.1是一个特殊的ip(环回IP),自己访问自己
        //如果服务器和客户端在同一台主机上使用回环ip,如果不在同一台主机上就必须填写服务器的ip
        //端口号必须与服务器的端口号一致
//        UDPEchoClient client = new UDPEchoClient("127.0.0.1",9090);
        UDPEchoClient client = new UDPEchoClient("47.98.116.42",9090);
        client.start();
    }
}

客户端跨主机通信过程

  • 客户端跨 主机通信可以实现跨主机
  • 要把服务器部署到云服务器上
  • 部署的步骤主要有两个
    1.把代码打成jar包
    2.把jar包拷贝到服务器上运行

用idea打jar包:

UDP实现客户端服务器网络编程_第1张图片
UDP实现客户端服务器网络编程_第2张图片

UDP实现客户端服务器网络编程_第3张图片
UDP实现客户端服务器网络编程_第4张图片
UDP实现客户端服务器网络编程_第5张图片
UDP实现客户端服务器网络编程_第6张图片
UDP实现客户端服务器网络编程_第7张图片
UDP实现客户端服务器网络编程_第8张图片

体会客户端服务器的基本工作流程

UDP实现客户端服务器网络编程_第9张图片
服务器
1.先初始化
在这里插入图片描述
2.进入主循环
在这里插入图片描述

3.读取请求并解析
UDP实现客户端服务器网络编程_第10张图片
客户端
1.先初始化
在这里插入图片描述
2.进入主循环
在这里插入图片描述
a)读取用户输入
UDP实现客户端服务器网络编程_第11张图片
b)构造请求给服务器
在这里插入图片描述
服务器
b)根据请求计算响应
在这里插入图片描述
c)把响应写给客户端
在这里插入图片描述
客户端
c)读取服务器响应
在这里插入图片描述
d)把响应写显示到界面上
在这里插入图片描述

实践翻译服务器(简单的英译汉)

先赞后看,养成习惯!!!^ _ ^♥♥♥
每天都更新知识点哦!!!
码字不易,大家的支持就是我坚持下去的动力。点赞后不要忘记关注我哦!

你可能感兴趣的:(网络,网络,udp,服务器)