网络编程Junit单元测试设计模式

网络编程|Junit单元测试|设计模式

网络编程

  • 在网络通信协议下,不同计算机上运行的程序,可以进行数据传输

网络编程三要素

  • IP地址
    • 设备在网络中的地址,是唯一的标识
  • 端口
    • 应用程序在设备中唯一的标识
  • 协议
    • 数据在网络中传输的规则,常见的协议有UDP协议和TCP协议
IP地址
  • IP:全程“互联网协议地址”,也称IP地址。是分配给上网设备的数字标签、常见的IP分类为:ipv4和ipv6

  • InetAddress的使用

    • 为了方便我们对IP地址的获取和操作,Java提供了一个类InetAddress供我们使用

    • InetAddress:此类表示Internet协议(IP)地址

      方法名说明
      static InetAddress getByName(String host)在给定主机名的情况下获取InetAddress类的对象
      String getHostName()获取此IP地址的主机名
      String getHostAddress()返回IP地址字符串(以文本表现形式)
端口
  • 端口号:应用程序的唯一标识方式,用两个字节表示的整数值,它的取值范围是065535,其中01023之间的端口号用于一些知名的网络服务或者应用。我们自己使用1024以上的端口号就可以了
  • 注意:一个端口号只能被一个应用程序使用
协议
  • UDP协议
    • 用户数据报协议(User Datagram Protocol)
    • UDP是面向无连接通信协议。速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据
  • TCP协议
    • 传输控制协议(Transmission Control Protocol)
    • TCP协议是面向连接的通信协议。速度慢,没有大小限制,数据安全

TCP通信程序

  • 客户端程序:Socket

    • 先找到计算机
    • 再找到计算机上的服务端程序
    • 按照TCP协议进行数据发送、接收
      • 基于IO流实现
    // 创建客户端Socket对象,并连接服务端程序
    Socket socket = new Socket("对方计算机IP地址", "服务端程序端口号");
    // 基于socket对象,获取网络输出流(发送数据)
    OutputStream netOut = socket.getOutputStream();
    // 发送数据
    netOut.write("数据".getBytes());
    // 关闭资源
    netOut.close();
    socket.close();
    
  • 服务端程序:ServerSocket

    • 绑定服务端程序端口号
    // 创建服务端Socket对象,并指定端口号
    ServerSocket ss = new ServerSocket(9090);
    // 监听客户端连接,获取到一个Socket对象
    Socket server = ss.accept();
    // 接收数据
    InputStream netIn = server.getInputStream();
    
    byte[] buf = new byte[1024];
    int len = netIn.read(buf);
    

    练习

    // 服务端代码
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TcpServer {
        public static void main(String[] args) throws IOException {
            ServerSocket ss = new ServerSocket(9999);
            System.out.println("服务器已启动。。。");
            Socket accept = ss.accept();
            System.out.println(accept.getInetAddress().getHostAddress() + "客户端已连接~");
            InputStream netInput = accept.getInputStream();
    
            byte[] buf = new byte[1024];
            netInput.read(buf);
            String s = new String(buf, 0, buf.length);
    
            System.out.println(s);
            netInput.close();
            ss.close();
        }
    }
    
    // 客户端代码
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    
    public class TcpClient {
        public static void main(String[] args) throws IOException {
            Socket client = new Socket("127.0.0.1", 9999);
    
            OutputStream netOutput = client.getOutputStream();
            netOutput.write("你好".getBytes());
    
            client.close();
        }
    }
    
    /*
    运行结果:
    	服务器已启动。。。
    	127.0.0.1客户端已连接~
    	你好 
    */
    
案例
  1. 需求

    • 客户端:将本地文件上传到服务器。接收服务器的反馈
    • 服务端:接收客户端上传的文件,上传完毕后给出反馈
    // 服务端代码
    port java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class TCPServer {
        public static void main(String[] args) throws IOException {
            String to = "to/target.jpg";
            ServerSocket ss = new ServerSocket(9999);
            System.out.println("服务端已启动。。。");
            Socket server = ss.accept();
            System.out.println(server.getInetAddress().getHostAddress() + "客户端已连接~");
            InputStream netInput = server.getInputStream();
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(to));
    
            int data = -1;
            while ((data = netInput.read()) != -1){
                bos.write(data);
            }
            System.out.println("上传文件接收完毕");
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(server.getOutputStream()));
            bw.write("文件上传成功!");
            bw.newLine();
    
            bw.close();
            bos.close();
            netInput.close();
            server.close();
        }
    }
    /*
    	服务端已启动。。。
    	127.0.0.1客户端已连接~
    	上传文件接收完毕
    */
    
    // 客户端代码
    import java.io.*;
    import java.net.Socket;
    
    public class TCPClient {
        public static void main(String[] args) throws IOException {
            String from = "from/a.jpg";
            Socket client = new Socket("127.0.0.1", 9999);
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(from));
            OutputStream netOutput = client.getOutputStream();
            System.out.println("文件正在上传中。。。");
            int len = -1;
            while ((len = bis.read()) != -1){
                netOutput.write(len);
            }
            client.shutdownOutput();//告知服务端文件发送完毕
    
            BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
            System.out.println(br.readLine());
    
            br.close();
            bis.close();
            netOutput.close();
            client.close();
    
        }
    }
    /*
    	文件正在上传中。。。
    	文件上传成功!
    */
    

设计模式

单例设计模式

  • 保证程序中运行的某个类只能创建一个对象(节省空间,共享数据)

  • 实现步骤:

    1. 将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象

    2. 在该类内部产生一个唯一的实例化对象,并且将其封装为private static 类型的成员变量

    3. 定义一个静态方法返回这个唯一对象

  • 单例设计模式的类型

    1. 饿汉单例设计模式:随着类的加载就把唯一对象创建完成

    2. 懒汉单例设计模式:当需要使用对象时才创建对象

多例设计模式

  • 多例模式是一种常用的设计模式之一。通过多例模式可以保证项目中,应用该模式的类有固定数量的实例,多例类要自我创建并管理自己的实例,还要向外界提供获取本类实例的方法
  • 实现步骤
    1. 创建一个类,将构造方法私有化,使其不能在类的外部通过new关键字实例化该类的对象
    2. 在类中定义该类被创建对象的总数量
    3. 在类中定义存放类实例的list集合
    4. 在类中提供静态代码块,在静态代码块中创建类的实例
    5. 提供获取类实例的静态方法

工厂设计模式

  • 工厂模式时java中最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式,之前我们创建类对象时,都是使用new对象的形式创建,除new对象方式之外,工厂模式也可以创建对象

  • 作用:解决了类与类之间的耦合问题

  • 案例

    // 汽车接口
    public interface Car {
        public abstract void run();
    }
    // 法拉利类
    public class Falali implements Car{
        @Override
        public void run() {
            System.out.println("法拉利");
        }
    }
    // 奔驰类
    public class Benchi implements Car{
        @Override
        public void run() {
            System.out.println("奔驰");
        }
    }
    // 汽车工厂类
    public class CarFactory {
        private CarFactory(){}
    
        public static Car getInstance(String name){
            Car car = null;
            if ("falali".equals(name)){
                car = new Falali();
            } else if ("benchi".equals(name)) {
                car = new Benchi();
            }
    
            return car;
        }
    }
    // bean.properties配置文件
    name = benchi
        
    // 测试类
    import java.util.ResourceBundle;
    
    public class Test {
        public static void main(String[] args) {
            ResourceBundle rb = ResourceBundle.getBundle("Bean");
            String name = rb.getString("name");
    
            Car c = CarFactory.getInstance(name);
            c.run();
        }
    }
    

Junit单元测试

  • 单元测试就是编写测试代码,可以准确、快速的保证程序的正确性,Junit时java单元测试的框架
  • JUnit4可以通过注解的方式来标记方法,让方法存在某种意义,常见的注解有:
    • @BeforeClass // 全局只会执行一次,而且时第一个运行(标记的方法需要是一个静态无参无返回值的方法)
    • @Before // 再测试方法运行之前运行(非静态无参无返回值方法)
    • @Test // 测试方法(此方法必须是非静态无参无返回值方法),主要用于测试的方法
    • @After // 在测试方法运行之后运行(非静态无参无返回值方法)
    • @AfterClass // 全局只会执行一次,而且是最后一个运行(标记的方法需要是一个静态无参无返回值方法)
    • @lgnore // 忽略此方法

断言的使用

// 第一个参数表示期望值
// 第二个参数表示实际值
// 如果实际值和期望值相同,说明结果正确就测试通过,如果不相同,说明结果是错误的,就会报错
Assert.assertEquals(期望值, 实际值);
Assert.assertEquals("异常原因", 期望值, 实际值);

// 例如
int result = add(100, 200);
Assert.assertEquals(300, result);
  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值