JUnit单元测试、网络编程

day12【JUnit单元测试、网络编程】

今日目标:
	a.Junit单元测试[重点]
    b.UDP
    c.TCP  
    d.http[重点,在服务器阶段学习]   

第一章.Junit单元测试

1.什么是单元测试
简单的理解: 单元测试就是可以取代main方法进行测试的技术
2.Junit的使用步骤
  • 下载

    http://www.junit.org
    大部分的开发工具(IDEA,Eclipse,MyEclipse)都会集成junit的jar包
    
  • 具体使用步骤

    a.编写被测试类(业务类)
    b.编写测试类
    c.在测试类编写测试方法(不需要main方法!!!)
    d.给测试方法加上junit提供的注解@Test    
    
  • 运行测试

    在Junit的测试方法上右键运行该方法
    在Junit的测试类上右键运行该类中所有的测试方法    
    
3.单元测试中其他四个注解
  • Junit4.x

     @Before 表示该方法会在每个测试方法执行之前执行
     @After  表示该方法会在每个测试方法执行之后执行  
     @BeforeClass 表示该方法会在所有测试方法执行之前执行
     @AfterClass  表示该方法会在所有测试方法执行之后执行  
     注意:@BeforeClass@AfterClass必须修饰静态方法  
    
  • Junit5.x

    @BeforeEach 表示该方法会在每个测试方法执行之前执行
    @AfterEach  表示该方法会在每个测试方法执行之后执行  
    @BeforeAll 表示该方法会在所有测试方法执行之前执行
    @AfterAll 表示该方法会在所有测试方法执行之后执行   
    注意:@BeforeAll@AfterAll必须修饰静态方法      
    

第二章 网络编程入门

1.软件架构介绍
BS架构: Browser(浏览器)/Server(服务器)
    比如: QQ,淘宝,京东
CS架构: Client(客户端)/Server(服务器)
    比如: QQ(微信),百度云,迅雷,淘宝,京东	
        
我们JavaEE主要学:服务器,但是也会学7天左右浏览器相关的语言        
2.网络通信协议介绍
网络通信协议:互联网上计算机之间数据交换需要遵循的规则  
3.常用的通信协议
IP协议: 规定每台连接到网络的计算机的唯一标识(IP地址)
UDP协议: 用户数据报协议
    特点: 面向无连接
    优点: 性能较高
	缺点: 数据不能保证安全性和完整性
    比如: 直播,QQ视频,供屏软件    
	
TCP协议: 传输控制协议
    特点: 面向有链接(建立连接的过程,称为"三次握手")
    优点: 保证数据是安全的和完整的
    缺点: 性能较低  
    比如: 下载游戏            
4.网络编程的三要素
网络协议(UDP和TCP):必须遵循的规则
IP地址: 计算机的唯一标识
端口号: 计算机中软件的标识 
    端口号有0-65535,我们开发时建议使用1024以上端口,因为1024以下端口被知名软件服务占用了
扩展:
  • IP地址的未来

    IPv4:32位二进制组成(4个字节),比如(192.168.109.23),一共有多个IP? 42亿种IP
    IPv6:128位二进制组成(16个字节),一共有多少个IP??号称可以给全球每一粒沙子搞一个IP,且不重复
    
  • IP地址的获取和测试(Dos命令)

    ipconfig: 查看本机IP
    ping 其他人IP: 测试网络是否畅通    
    
  • 特殊的IP地址

    127.0.0.1(localhost)
    本机IP(相当于Java中this)    
    

第三章 UDP通信

1.UDP协议概述
UDP特点: 面向无连接
    * 面向无连接的协议 
    * 发送端只管发送,不确认对方是否能收到。 
    * 基于数据包进行数据传输。 
    * 发送数据的大小限制64K以内 
    * 因为面向无连接,速度快,但是不可靠。
UDP协议的使用场景 
    * 即时通讯 
    * 在线视频 
    * 网络语音电话	
2.UDP的发送端类和数据包类
a.数据发送/接收器: DatagramSocket
DatagramSocket
    构造方法:
		public DatagramSocket(); -- 一般用于发送端
		public DatagramSocket(int port); -- 一般用于接收端
	成员方法:
		public void send(DatagramPacket dp); -- 发送数据包
		public void receive(DatagramPacket dp); -- 接收数据包
    
b.数据包类 : DatagramPacket 
DatagramPacket
    构造方法:
		public DatagramPacket(byte[] buf, int length, InetAddress address, int port);
						   要发送的字节数组,要发送的字节数组长度,接收人的IP地址,接收人的端口号
		public DatagramPacket(byte[] buf, int length);
							接收数据的字节数组,数组中用于接收数据的长度
3.UDP通信案例
/**
 * UDP发送端
 */
public class UDPSender {
    public static void main(String[] args) throws IOException {
        //1.创建一个发送器对象
        DatagramSocket ds = new DatagramSocket();
        //2.创建一个数据报对象
        byte[] bs = "Hello,我是发送端".getBytes();
        DatagramPacket dp = new DatagramPacket(bs,bs.length, InetAddress.getByName("127.0.0.1"),12345);
        //3.发送数据
        ds.send(dp);
        System.out.println("发送成功...");
        //4.释放资源
        ds.close();
    }
}

/**
 * UDP接收端
 */
public class UDPReceiver {
    public static void main(String[] args) throws IOException {
        //1.创建一个接收器对象
        DatagramSocket ds = new DatagramSocket(12345);
        //2.创建一个数据报对象
        byte[] bs = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bs, bs.length);
        //3.接收数据包
        System.out.println("等待发送端的信息...");
        ds.receive(dp); // 该方法具有阻塞功能,直到有发送端发送信息
        System.out.println("发送端发来信息...");
        //输出一下
        int len = dp.getLength();
        byte[] data = dp.getData();
        System.out.println("发送端发来贺电:" + new String(data, 0, len));
        //4.释放
        ds.close();
    }
}

第四章 TCP通信

1.TCP通信分为客户端和服务器
客户端: 一般是指个人电脑(配置较低)
服务器端: 一般是指企业电脑(配置较高)    
2.TCP中的两个重要的类
Socket(套接字),代表客户端的类
ServerSocket(服务器套接字),代表服务器的类    
3.Socket类的介绍和使用
  • 构造方法

    public Socket(String host, int port); 创建客户端时,要指定服务器的IP和端口号
    该构造非常牛逼,
    	如果指定的服务器存在,那么构造方法自动和服务器通过TCP建立连接,对象成功创建
        如果指定的服务器不存在,那么该构造方法直接抛出异常    
    
  • 常用方法

    public OutputStream getOutputStream(); 获取连接通道中的输出流
    public InputStream getInputStream(); 获取连接通道中的输入流   
        
    public void shutDownOutput(); 关闭连接通道中的输出流
    public void shutDownInput(); 关闭连接通道中的输入流   
        
    public void close(); 关闭客户端,与服务器断开连接(连接通道中的流也会自动关闭)    
    
4.ServerSocket类的介绍和使用
  • 构造方法

    public ServerSocket(int port); 创建服务器,指定服务器所在的端口号
    
  • 常用的成员方法

    public void close(); 关闭服务器(断开所有客户端连接)
    public Socket accept(); 接收客户端连接,返回连接到的客户端对象    
    
5.简单的TCP通信实现(单向通信)
/**
 * TCP的客户端
 */
public class TCPClient {
    public static void main(String[] args) throws IOException, InterruptedException {
        //1.创建客户端,同时连接服务器
        Socket s = new Socket("127.0.0.1",54321);
        System.out.println("服务器连接成功...");
        //2.获取通道中的输出流
        OutputStream out = s.getOutputStream();
        //3.调用out的write方法
        Thread.sleep(5000);
        out.write("你好,服务器,我是客户端,你大爷我来了...".getBytes());
        System.out.println("数据发送成功...");
        //4.释放资源
        out.close();
        s.close();
        System.out.println("客户端关闭成功...");
    }
}
/**
 * TCP服务器端
 */
public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器
        ServerSocket server = new ServerSocket(54321);
        System.out.println("服务器启动..");
        //2.等待接收客户端
        System.out.println("等待客户端...");
        Socket s = server.accept(); // 此方法具有阻塞功能
        System.out.println("客户端来了...");
        //3.获取通道中的输入流
        InputStream in = s.getInputStream();
        //4.调用in的read方法
        byte[] bs = new byte[1024];
        System.out.println("正在接收客户端数据...");
        int len = in.read(bs); // 此方法具有阻塞功能
        System.out.println("客户端说:" + new String(bs, 0, len));
        //5.释放资源
        in.close();
        s.close();
        server.close();
        System.out.println("服务器关闭成功...");
    }
}
注意: 在服务器端有两个方法具有阻塞功能
     a.server.accept() 等待客户端连接方法
     b.in.read(bs) 等待客户端发送数据
6.简单的TCP通信实现(双向通信)
/**
 * TCP的客户端
 */
public class TCPClient {
    public static void main(String[] args) throws IOException, InterruptedException {
        //1.创建客户端,同时连接服务器
        Socket s = new Socket("127.0.0.1",54321);
        System.out.println("服务器连接成功...");
        //2.获取通道中的输出流
        OutputStream out = s.getOutputStream();
        //3.调用out的write方法
        Thread.sleep(5000);
        out.write("你好,服务器,我是客户端,你大爷我来了...".getBytes());
        System.out.println("数据发送成功...");
        //===========双向===========
        //4.获取通道中的输入流
        InputStream in = s.getInputStream();
        //5.调用in的read方法
        System.out.println("等待服务器回信..");
        byte[] bs = new byte[1024];
        int len = in.read(bs); // 此方法也具有阻塞功能
        System.out.println("服务器说:" + new String(bs, 0, len));
        //===========双向===========
        //6.释放资源
        in.close();
        out.close();
        s.close();
        System.out.println("客户端关闭成功...");
    }
}

注意:客户端中有一个方法具有阻塞功能
    a.in.read(bs) 读取服务器回复的信息
/**
 * TCP服务器端
 */
public class TCPServer {
    public static void main(String[] args) throws IOException, InterruptedException {
        //1.创建一个服务器
        ServerSocket server = new ServerSocket(54321);
        System.out.println("服务器启动..");
        //2.等待接收客户端
        System.out.println("等待客户端...");
        Socket s = server.accept(); // 此方法具有阻塞功能
        System.out.println("客户端来了...");
        //3.获取通道中的输入流
        InputStream in = s.getInputStream();
        //4.调用in的read方法
        byte[] bs = new byte[1024];
        System.out.println("正在接收客户端数据...");
        int len = in.read(bs); // 此方法具有阻塞功能
        System.out.println("客户端说:" + new String(bs, 0, len));
        //===========双向===========
        //5.获取通道中的输出流
        OutputStream out = s.getOutputStream();
        //6.调用输出流的write方法
        Thread.sleep(5000);
        out.write("您的消息收到了,您可以安息了...".getBytes());
        System.out.println("数据回复成功...");
        //===========双向===========
        //7.释放资源
        out.close();
        in.close();
        s.close();
        server.close();
        System.out.println("服务器关闭成功...");
    }
}
注意: 在服务器端有两个方法具有阻塞功能
     a.server.accept() 等待客户端连接方法
     b.in.read(bs) 等待客户端发送数据

第五章 综合案例:文件上传

1.文件上传案例分析(画图演示)
image-20200102154655551
2.文件上传案例实现(代码演示)
/**
 * 文件上传的客户端
 */
public class FileUploadClient {
    public static void main(String[] args) throws IOException {
//        1.创建客户端连接服务器
        Socket client = new Socket("127.0.0.1",6666);
        System.out.println("服务器连接成功...");
//        2.获取输出流
        OutputStream out = client.getOutputStream();
//        3.创建文件的输入流
        FileInputStream fis = new FileInputStream("222.png");
//        循环:一边读文件
//                一边发数据
        byte[] bs = new byte[1024];
        int len = 0;
        System.out.println("正在给服务器发送文件...");
        while ((len = fis.read(bs)) != -1) {
            out.write(bs, 0, len);
        }
        client.shutdownOutput();
        System.out.println("文件发送完毕...");
//        4.获取输入流
        InputStream in = client.getInputStream();
//        5.调用输入流的read方法
        byte[] bs1 = new byte[1024];
        System.out.println("正在接收服务器的回复...");
        int len1 = in.read(bs1);
        System.out.println("服务器回复:" + new String(bs1, 0, len1));
//        6.释放资源
        in.close();
        fis.close();
        out.close();
        client.close();
        System.out.println("客户端关闭...");
    }
}
/**
 * 文件上传服务器端
 */
public class FileUploadServer {
    public static void main(String[] args) throws IOException {
//        1.创建服务器对象
        ServerSocket server = new ServerSocket(6666);
        System.out.println("服务器启动成功...");
//        2.接收客户端对象
        System.out.println("等待客户端...");
        Socket client = server.accept();
        System.out.println("客户端来了..."+client.getInetAddress().getHostAddress());
//        3.获取输入流
        InputStream in = client.getInputStream();
//        4.创建文件的输出流
        FileOutputStream fos = new FileOutputStream("G:\\uploads\\copy.png");
//        循环: 一边读数据
//                一边写文件
        byte[] bs = new byte[1024];
        int len = 0;
        System.out.println("正在接收文件....");
        while ((len = in.read(bs)) != -1) {
            fos.write(bs, 0, len);
        }
        System.out.println("文件接收完毕...");
//        5.获取输出流
        OutputStream out = client.getOutputStream();
//        6.调用输出流的write方法
        out.write("您的文件收到了".getBytes());
        System.out.println("给客户端回复信息完毕..");
//        7.释放资源
        out.close();
        fos.close();
        in.close();
        client.close();
        server.close();
        System.out.println("服务器关闭!!");
    }
}
3.文件上传案例实现的不足之处
a.文件名固定,导致无论上传多少张图片,只剩最后一张
b.服务器每次启动只能服务一个客户端 
c.客户端文件很大,服务器无法接收下一个客户端    
4.文件上传案例的优化实现(代码演示)
a.文件名固定,导致无论上传多少张图片,只剩最后一张
    优化:将图片的名字改为当前的毫秒值
b.服务器每次启动只能服务一个客户端 
    给服务器添加死循环,永不停止的接收下一个客户端    
c.客户端文件很大,服务器无法接收下一个客户端  
    接收到客户端之后,创建一个线程,与该客户端进行交互,主线立即等待下一个客户端    

/**
 * 文件上传服务器端
 */
public class FileUploadServer {
    public static void main(String[] args) throws IOException {
//        1.创建服务器对象
        ServerSocket server = new ServerSocket(6666);
        System.out.println("服务器启动成功...");
//        2.接收客户端对象
        while (true) {
            System.out.println("等待客户端...");
            Socket client = server.accept();
            System.out.println("客户端来了..." + client.getInetAddress().getHostAddress());
            //创建线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //        3.获取输入流
                        InputStream in = client.getInputStream();
//        4.创建文件的输出流
                        FileOutputStream fos = new FileOutputStream("G:\\uploads\\" + System.currentTimeMillis() + ".png");
//        循环: 一边读数据
//                一边写文件
                        byte[] bs = new byte[1024];
                        int len = 0;
                        System.out.println("正在接收文件....");
                        while ((len = in.read(bs)) != -1) {
                            fos.write(bs, 0, len);
                        }
                        System.out.println("文件接收完毕...");
//        5.获取输出流
                        OutputStream out = client.getOutputStream();
//        6.调用输出流的write方法
                        out.write("您的文件收到了".getBytes());
                        System.out.println("给客户端回复信息完毕..");
//        7.释放资源
                        out.close();
                        fos.close();
                        in.close();
                        client.close();
                    } catch (IOException ie) {
                        ie.printStackTrace();
                        System.out.println("客户端有异常");
                    }
                }
            }).start();
        }
//        server.close();
//        System.out.println("服务器关闭!!");
    }
}
5.模拟BS架构服务器(了解)
BS架构中,B是浏览器,替代客户端
public class BSServer {
    public static void main(String[] args) throws IOException {
        //1.创建服务器
        ServerSocket server = new ServerSocket(8888);
        //2.等待客户端(浏览器)
        Socket browser = server.accept(); // 阻塞
        //3.获取输入流
        InputStream in = browser.getInputStream();
        //4.读数据
//        byte[] bs = new byte[1024];
//        int len = in.read(bs);
//        System.out.println(new String(bs, 0, len));
        //4.只需要读第一行 第二部分中的信息
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String line = br.readLine();
        String[] names = line.split(" ");
        String filename = names[1].substring(1);
        System.out.println("浏览器想要:"+filename);
        //5.把浏览器想要的文件,读取出来,发送给浏览器
        //获取输出流
        OutputStream out = browser.getOutputStream();
        FileInputStream fis = new FileInputStream(filename);
        byte[] bs = new byte[1024];
        int len = 0;
        out.write("HTTP/1.1 200 OK\r\n".getBytes());
        out.write("Content-Type:text/html\r\n".getBytes());
        out.write("\r\n".getBytes());
        while ((len = fis.read(bs)) != -1) {
            out.write(bs, 0, len);
        }
        //5.释放资源
        in.close();
        browser.close();
        server.close();
    }
}    
6.扩展:模拟服务器扩展_图片显示问题(了解)
a.服务器要永不停止
b.修改html添加图片
    <html>
        <head>
            <title>黑马收费处</title>
        </head>
        <body>
            请扫描以下二维码付款(打八折)<br/>
            <img src="111.png" width="20%"/>
        </body>
    </html>
总结

猜你喜欢

转载自blog.csdn.net/qq_41371264/article/details/103864109
今日推荐