首页 > 编程语言 >java网络编程 , 网络编程 , Junit单元测试概念及使用方法详细介绍

java网络编程 , 网络编程 , Junit单元测试概念及使用方法详细介绍

时间:2024-06-22 14:33:10浏览次数:13  
标签:java socket 编程 网络 import new public Socket

网络编程

主要内容

  • 网络编程
  • TCP通信
  • Junit单元测试

1 网络编程

1.1 软件架构

  • C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件
  • B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等
  • 两种架构各有优势,但是都离不开网络的支持。网络编程 , 就是在一定的协议下,实现两台计算机的通信的程序
  • 在这里插入图片描述

1.2 什么是网络编程

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

1.3 网络编程三要素

  • IP地址 : 设备在网络中的地址,是唯一的标识。
  • 端口 : 设备在网络中的地址,是唯一的标识。
  • 数据在网络中传输的规则,常见的协议有UDP协议和TCP协议。

1.4 IP地址

  • IP:全称”互联网协议地址”,也称IP地址。是分配给上网设备的数字标签。常见的IP分类为:ipv4和ipv6

    简单来说 : 就是设备在网络中的唯一标识 , 想要连接哪一台电脑 , 就找到此电脑在网络中的ip地址

  • IP地址常见分类 : ipv4和ipv6

  • 常用命令:

    • ipconfig:查看本机IP地址
    • IP地址:检查网络是否连通
  • 特殊IP地址:

    • 127.0.0.1:是回送地址也称本地回环地址,可以代表本机的IP地址,一般用来测试使用
  • 为了方便我们对IP地址的获取和操作,Java提供了一个类InetAddress 供我们使用
    InetAddress:此类表示Internet协议(IP)地址

    • static InetAddress getByName(String host)在给定主机名的情况下确定主机的 IP 地址
      String getHostName()获取此 IP 地址的主机名
      String getHostAddress()返回 IP 地址字符串(以文本表现形式)。

1.5 端口

  • 端口:应用程序在设备中唯一的标识。
  • 端口号:应用程序的唯一标识方式 , 用两个字节表示的整数,它的取值范围是0~65535。
    其中0~1023之间的端口号用于一些知名的网络服务或者应用。
    我们自己使用1024以上的端口号就可以了。
  • 注意:一个端口号只能被一个应用程序使用。

1.6 通信协议

  • 协议:计算机网络中,连接和通信的规则被称为网络通信协议
  • UDP协议
    • 用户数据报协议(User Datagram Protocol)
    • UDP是面向无连接通信协议。
    • 速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据。
  • TCP协议
    • 传输控制协议 (Transmission Control Protocol)
    • TCP协议是面向连接的通信协议。
    • 速度慢,没有大小限制,数据安全

2 网络编程

2.1 TCP发送数据

package com.itheima.tcp_demo.demo1;

import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

/*
    客户端 :

    发送数据的步骤
        1 创建客户端的Socket对象 : Socket(String host, int port) 与指定服务端连接
            参数说明:
            host 表示服务器端的主机名,也可以是服务器端的IP地址,只不过是String类型的
            port 表示服务器端的端口

        2 通获Socket对象取网络中的输出流,写数据
            OutputStream getOutputStream()

        3 释放资源
            void close()

 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 创建客户端的Socket对象(Socket) 与指定服务端连接
        Socket socket = new Socket("127.0.0.1", 10010);

        // 通获Socket对象取网络中的输出流,写数据
        OutputStream os = socket.getOutputStream();
        os.write("hello".getBytes());

        // while(true){}

        // 释放资源
        os.close();
        socket.close();
    }
}

2.2 TCP接收数据

package com.itheima.tcp_demo.demo1;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/*
     服务端接收数据 :

    1 创建服务器端的Socket对象 : ServerSocket类
        ServerSocket(int port)  : 构造方法需要绑定一个端口号 , port就是端口号

    2 监听客户端连接,并接受连接,返回一个Socket对象
        Socket accept() : 该方法会一直阻塞直到建立连接

    3 获取网络中的输入流,用来读取客户端发送过来的数据
        InputStream getInputStream()

    4 释放资源 : 服务端一般不会关闭
        void close()
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
//        1 创建服务器端的Socket对象 : ServerSocket类
//        ServerSocket(int port)  : 构造方法需要绑定一个端口号 , port就是端口号
        ServerSocket serverSocket = new ServerSocket(10010);

//        2 监听客户端连接,并接受连接,返回一个Socket对象
//        Socket accept() : 该方法会一直阻塞直到建立连接
        Socket socket = serverSocket.accept();
//
//        3 获取网络中的输入流,用来读取客户端发送过来的数据
//        InputStream getInputStream()
        InputStream is = socket.getInputStream();
        int by;
        System.out.println("read方法执行前");
        while ((by = is.read()) != -1) {
            System.out.print((char) by);
        }
        System.out.println("read方法执行后");
    }
}

2.3 TCP通信原理分析

在这里插入图片描述

2.4 TCP三次握手

在这里插入图片描述

2.5 TCP练习1

package com.itheima.tcp_demo.test1;

import java.io.*;
import java.net.Socket;

/*
    客户端 :

    发送数据的步骤
        1 创建客户端的Socket对象 : Socket(String host, int port) 与指定服务端连接
            参数说明:
            host 表示服务器端的主机名,也可以是服务器端的IP地址,只不过是String类型的
            port 表示服务器端的端口

        2 通获Socket对象取网络中的输出流,写数据
            OutputStream getOutputStream​()

        3 释放资源
            void close​()

 */
public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 创建客户端的Socket对象(Socket) 与指定服务端连接
        Socket socket = new Socket("127.0.0.1", 10010);

        // 通获Socket对象取网络中的输出流,写数据
        OutputStream os = socket.getOutputStream();
        os.write("hello".getBytes());
        // 像服务端写入结束标记
        socket.shutdownOutput();

        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = br.readLine();
        System.out.println(line);

        // 释放资源
        br.close();
        os.close();
        socket.close();
    }
}

package com.itheima.tcp_demo.test1;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*
     服务端接收数据 :

    1 创建服务器端的Socket对象 : ServerSocket类
        ServerSocket​(int port)  : 构造方法需要绑定一个端口号 , port就是端口号

    2 监听客户端连接,并接受连接,返回一个Socket对象
        Socket accept​() : 该方法会一直阻塞直到建立连接

    3 获取网络中的输入流,用来读取客户端发送过来的数据
        InputStream getInputStream​()

    4 释放资源 : 服务端一般不会关闭
        void close​()
 */
public class ServerDemo {
    public static void main(String[] args) throws IOException {
//        1 创建服务器端的Socket对象 : ServerSocket类
//        ServerSocket​(int port)  : 构造方法需要绑定一个端口号 , port就是端口号
        ServerSocket serverSocket = new ServerSocket(10010);

//        2 监听客户端连接,并接受连接,返回一个Socket对象
//        Socket accept​() : 该方法会一直阻塞直到建立连接
        Socket socket = serverSocket.accept();
//
//        3 获取网络中的输入流,用来读取客户端发送过来的数据
//        InputStream getInputStream​()
        InputStream is = socket.getInputStream();
        int by;

        while ((by = is.read()) != -1) {
            System.out.print((char) by);
        }

        BufferedWriter bos = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bos.write("你谁啊");

        bos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

2.6 TCP练习2

package com.itheima.tcp_demo.test2;

import java.io.*;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 创建客户端Socket对象
        Socket socket = new Socket("127.0.0.1", 10086);

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\传智播客\\安装包\\好看的图片\\liqin.jpg"));

        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());

        int by;
        while ((by = bis.read()) != -1) {// 从本地中读一个字节
            bos.write(by);// 往服务器写一个字节
            bos.flush();
        }
        // 写结束标记
        socket.shutdownOutput();

        // 把网络中的字节输入流 , 封装成高效的字符输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//        String line;
//        while ((line = br.readLine()) != null) {
//            System.out.println(line);
//        }
        String msg = br.readLine();// 读到换行才叫读到一行, 所以必须写服务器必须写newLine
        System.out.println(msg);

        // 释放资源
        bis.close();
        socket.close();
    }
}

package com.itheima.tcp_demo.test2;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 创建服务端的连接对象
        ServerSocket serverSocket = new ServerSocket(10086);
        Socket socket = null;
        BufferedInputStream bis = null;
        BufferedWriter socketBw = null;

        while (true) {
            // 获取Socket对象
            socket = serverSocket.accept();

            // 获取网络中的字节输入流  在封装成高效的字节输入流对象
            bis = new BufferedInputStream(socket.getInputStream());

            // 创建本地的字节输出流 , 封装成高效的字节输出流
            BufferedOutputStream bw = new BufferedOutputStream(new FileOutputStream("day13_demo\\图片\\a.jpg"));

            int by;
            while ((by = bis.read()) != -1) {
                bw.write(by);
                bw.flush();
            }

            //关闭本地流
            bw.close();

            // 获取网络中的字节输出流 , 封装成高效的字符输出流
            socketBw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            socketBw.write("谢谢你");
            socketBw.newLine();// 必须有换行 , 因为readLine读到换行结束
            socketBw.flush();
        }

        // 释放资源
//        socketBw.close();
//        bis.close();
//        socket.close();
//        serverSocket.close();
    }
}

2.7 TCP练习3

package com.itheima.tcp_demo.test3;

import java.io.*;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
        // 创建客户端Socket对象
        Socket socket = new Socket("127.0.0.1", 10086);

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\传智播客\\安装包\\好看的图片\\liqin.jpg"));

        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());

        int by;
        while ((by = bis.read()) != -1) {// 从本地中读一个字节
            bos.write(by);// 往服务器写一个字节
            bos.flush();
        }
        // 写结束标记
        socket.shutdownOutput();

        // 把网络中的字节输入流 , 封装成高效的字符输入流
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//        String line;
//        while ((line = br.readLine()) != null) {
//            System.out.println(line);
//        }
        String msg = br.readLine();// 读到换行才叫读到一行, 所以必须写服务器必须写newLine
        System.out.println(msg);

        // 释放资源
        bis.close();
        socket.close();
    }
}

package com.itheima.tcp_demo.test3;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
        // 创建服务端的连接对象
        ServerSocket serverSocket = new ServerSocket(10086);

        ExecutorService executorService = Executors.newFixedThreadPool(10);
        while (true) {
            // 获取Socket对象
            Socket socket = serverSocket.accept();
            executorService.submit(new ServerThread(socket));
        }

        // 释放资源
//        socketBw.close();
//        bis.close();
//        socket.close();
//        serverSocket.close();
    }
}

package com.itheima.tcp_demo.test3;

import javax.management.relation.RoleUnresolved;
import java.io.*;
import java.net.Socket;
import java.util.UUID;

public class ServerThread implements Runnable {
    Socket socket = null;
    BufferedOutputStream bw = null;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {

        try {
            // 获取网络中的字节输入流  在封装成高效的字节输入流对象
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());

            // 创建本地的字节输出流 , 封装成高效的字节输出流
            bw = new BufferedOutputStream(new FileOutputStream("day13_demo\\图片\\" + UUID.randomUUID() + ".jpg"));

            int by;
            while ((by = bis.read()) != -1) {
                bw.write(by);
                bw.flush();
            }
            // 获取网络中的字节输出流 , 封装成高效的字符输出流
            BufferedWriter socketBw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            socketBw.write("谢谢你");
            socketBw.newLine();// 必须有换行 , 因为readLine读到换行结束
            socketBw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭本地流
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3 Junit单元测试

3.1 Junit4单元测试概述

  • 单元测试就是编写测试代码,可以准确、快速地保证程序的正确性,Junit是Java单元测试的框架。

  • JUnit4可以通过注解的方式来标记方法 , 让方法存某种意义 ,常见的注解有:

    • @BeforeClass 全局只会执行一次,而且是第一个运行(标记的方法需要是一个静态无参无返回值方法)
    • @Before 在测试方法运行之前运行(非静态无参无返回值方法)
    • **@Test 测试方法(此方法必须是非静态无参无返回值方法), 主要用于测试的方法 **
    • @After 在测试方法运行之后运行(非静态无参无返回值方法)
    • @AfterClass 全局只会执行一次,而且是最后一个运行(标记的方法需要是一个静态无参无返回值方法)
    • @Ignore 忽略此方法

================================================================================================================

3.2 Junit的基本使用

  • 已知存在需要测试的类Calculator ,这是一个能够简单实现加减乘除、平方、开方的计算器类,然后对这些功能进行单元测试。
// 计算器类
public class Calculator {
    // 静态变量,用于存储运行结果
    private static int result; // 20
  
    // 加法运算
    public void add(int n) {
        result = result + n;
    }
    
    // 减法运算
    public void subtract(int n) {
        // Bug: 正确的应该是 result = result - n
        result = result - 1;  
    }
  
    // 乘法运算
    public void multiply(int n) {
        // 此方法尚未写好
    }         
  
    // 除法运算
    public void divide(int n) {
        result = result / n;
    }
    
    // 平方运算
    public void square(int n) {
        result = n * n;
    }
    
    // 平方根运算
    public void squareRoot(int n) {
        // Bug : 死循环
        for (; ;) ;            
    }
    
    // 将结果清零
    public void clear() {     
        result = 0;
    }
    
    // 返回运算结果
    public int getResult(){
        return result;
    }
}
  • 引入Junit4的jar包到模块中
    • 第一步 : 在模块中新建文件夹lib,拷贝今天资料中junit4的jar包到模块中
      在这里插入图片描述

    • 第二步 : 选中jar文件 , 右键选择 Add as Library

  • 生成Junit测试框架
    • 使用IDEA能够直接给需要测试的类生成测试框架,如下:

    • 选中本类任何位置右键选择 Generate(Alt+Insert)/ go to 选项 , 选择Test…

      在这里插入图片描述

    • 选择需要进行测试的方法

    • 在这里插入图片描述

    • 在上一步OK后系统会自动生成一个新类CalculatorTest,里面包含一些空的测试用例。

      你只需要将这些测试用例稍作修改即可使用,完整的CalculatorTest代码如下:

      
      
  • 限时测试

    对于那些逻辑很复杂,循环嵌套比较深的程序,很有可能出现死循环,因此一定要采取一些预防措施。限时测试是一个很好的解决方案。我们给这些测试函数设定一个执行时间,超过了这个时间,他们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因是因为超时,这样你就可以发现这些Bug了。要实现这一功能,只需要给@Test标注加一个参数即可,代码如下:

    被测方法:

    public void squareRoot(int n) {
        //Bug : 死循环
        for (; ; ) ;            
    }
    
    测试方法:
    @Test(timeout = 1000)
    // Timeout参数表明了你要设定的时间,单位为毫秒,因此1000就代表1秒。
    public void squareRoot() {
        calculator.squareRoot(4);
        assertEquals(2 , calculator.getResult());
    }
    

3.3 断言

  • 概述 :

​ 预先判断某个条件一定成立,如果条件不成立,则直接报错。

  • 使用 :
    //第一个参数表示期望值
    //第二个参数表示实际值
    // 如果实际值和期望值相同,说明结果正确就测试通过,如果不相同,说明结果是错误的,就会报错
    Assert.assertEquals( 期望值, 实际值);
    Assert.assertEquals("异常原因", 期望值, 实际值);
    
    //例如:
    int result = add(100,200);
    Assert.assertEquals(300, result);  
    
  • 小结 : 如何进行断言
    Assert.assertEquals(期望值,实际值)
    

标签:java,socket,编程,网络,import,new,public,Socket
From: https://blog.csdn.net/xiugtt6141121/article/details/139882044

相关文章

  • java单例设计模式 , 多例设计模式 , 工厂设计模式概念及详细介绍
    单例设计模式正常情况下一个类可以创建多个对象publicstaticvoidmain(String[]args){ //正常情况下一个类可以创建多个对象 Personp1=newPerson(); Personp2=newPerson(); Personp3=newPerson();}如果说有时一个对象就能搞定的事情,非要创建多......
  • Java 接口
    本篇学习接口,并区分接口与抽象类两者之间的异同点。上篇已经讲解了抽象类,有需要的小伙伴可以点链接康康https://blog.csdn.net/m0_73107796/article/details/139863674目录1、什么是接口2、接口定义格式3、接口的使用 4、接口特性5、抽象类与接口的区别 1、什......
  • DVWA 靶场 JavaScript 通关解析
    前言DVWA代表DamnVulnerableWebApplication,是一个用于学习和练习Web应用程序漏洞的开源漏洞应用程序。它被设计成一个易于安装和配置的漏洞应用程序,旨在帮助安全专业人员和爱好者了解和熟悉不同类型的Web应用程序漏洞。DVWA提供了一系列的漏洞场景和练习环境,用户可以通过......
  • .Net开发 ,Java开发 ,python开发 数据库开发,开发相关工具
    开发电脑安装相关工具软件Java开发Java编程、高级编程、面试题资料Python编程,网络编程,爬虫,面试,设计资料数据库mysql,sqlservice,sql优化资料C#语言、.Net开发、.Net高级编程资料......
  • Java 8 Stream
    Java8StreamJava8新特性Java8新特性Java8API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream使用一种类似用SQL语句从数据库查询数据的直观方式来提供一种对Java集合运算和表达的高阶抽象。StreamAPI可以极大提高Java程序员的生产力,......
  • java多线程编程问题以及解决办法
    java多线程编程问题以及解决办法  多线程编程虽然可以提高程序的性能和响应速度,但也带来了许多复杂的问题,如竞态条件、死锁、线程安全问题、内存一致性错误等。常用的解决方法包括使用同步机制(如synchronized和ReentrantLock)、线程池、volatile关键字、以及合适的线程间......
  • 【JavaScript脚本宇宙】终极对决:六大虚拟DOM库横评
    深度剖析:六大虚拟DOM库的奥秘与应用场景前言虚拟DOM(DocumentObjectModel)是用于表示和操作HTML文档的抽象数据结构。虚拟DOM库是构建用户界面的重要工具,它们提供了高效的更新机制、组件化开发等功能,使开发者能够轻松地开发高性能、可维护的Web应用程序。本文将介绍几个流......
  • 【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验6 生成树协议STP的功能
    一、实验目的1.验证以太网交换机生成树协议的功能;2.理解网络环路对网络的负面效应;3.理解生成树协议的作用。二、实验要求1.使用CiscoPacketTracer仿真平台;2.观看B站湖科大教书匠仿真实验视频,完成对应实验。三、实验内容1.构建网络拓扑;2.发送报文,理解生成树协议ST......
  • 【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验7 虚拟局域网VLAN
    一、实验目的1.学习如何划分VLAN;2.验证划分VLAN的作用;3.学习如何用命令行创建VLAN,将端口划分到VLAN,设置端口类型。二、实验要求1.使用CiscoPacketTracer仿真平台;2.观看B站湖科大教书匠仿真实验视频,完成对应实验。三、实验内容1.构建网络拓扑;2.划分VLAN;3.发送ICM......
  • 基于javaweb房产中介房屋租赁系统设计与实现
      博主介绍:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;专注大学生毕业设计教育和辅导。所有项目都配有从入门到精通的基础知识视频课程,学习后应对毕业设计答辩。项目配有对应开发文档、开题报告、任务书......