栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

day12-Junit单元测试、Socket网络编程

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

day12-Junit单元测试、Socket网络编程

学习目标
- 能够使用Junit进行单元测试
	1.在当前模块下新建lib文件夹,拷贝junit的jar包,把jar包添加到图书馆中
	2.在要执行的方法上添加一个@Test注解
	3.点击方法左边的绿色三角或者右键选择方法,选择run 方法名称运行方法
- 能够辨别UDP和TCP协议特点
	udp:面向无连接的协议,通信双方不用连接连接,可以直接发送数据(视频聊天,视频会议...)
		好处:效率高,耗资小
		弊端:容易丢失数据
	tcp:面向连接的协议,客户端和服务器必须经过3次握手建立逻辑连接,才能通信(文件的上传和下载,发送文件...)
		好处:安全
		弊端:效率低
- 能够说出TCP协议下两个常用类名称
	客户端:Socket
	服务器:ServerSocket  accpet获取客户端
- 能够编写TCP协议下字符串数据传输程序
	笔记中:TCP通信程序(重点)
- 能够理解TCP协议下文件上传案例(重点)
	客户端:读取客户端硬盘上的文件,把文件上传到服务器,读取服务器回写的"上传成功!"
	服务器:读取客户端上传的文件,把文件保存到服务器的硬盘上,给客户端回写"上传成功!"
- 能够理解TCP协议下BS案例(看图)
	1.使用浏览器作为客户端访问服务器的某一个资源(index.html)
	http://localhost:8080/day12/web/index.html==>URL 统一资源定位符
	2.在服务器中获取客户端请求的资源路径(web/index.html)
	3.服务器使用本地字节输入流,根据路径读取index.html文件
	4.服务器在使用网络字节输出流,把读取到的index.html文件,写到客户端浏览器中显示
第一章 Junit单元测试 1.Junit介绍

Junit是一个Java语言的单元测试框架,简单理解为可以用于取代java的(部分)main方法。Junit属于第三方工具,需要导入jar包后使用。

2.Junit的基本使用(重点)

a.在当前模块下创建lib文件夹

b.把junit的jar包,拷贝到lib的文件夹中

c.把jar包添加到图书馆中



package com.itheima.demo01junit;

import org.junit.Test;


public class Demo01Junit {
   @Test
   public void show01(){
       System.out.println("show01方法");
   }

   @Test
    public void show02(){
        System.out.println("show02方法");
    }

    @Test
    public void show03(){
        System.out.println("show03方法1");
        System.out.println("show03方法2");
        System.out.println("show03方法3");
        System.out.println("show03方法4");
    }
}


3.Junit的注意事项
package com.itheima.demo01junit;

import org.junit.Test;


public class Demo02Junit {
   public void show01(){
       System.out.println("Demo02Junit show01方法");
   }

   //java.lang.Exception: Method show02 should have no parameters 方法show02应该没有参数
   //@Test
    public void show02(int a){
        System.out.println("Demo02Junit show02方法"+a);
    }

    //java.lang.Exception: Method show03() should be void 方法show03应该返回值类型是void
    //@Test
    public String show03(){
        System.out.println("Demo02Junit show03方法");
        return "你好";
    }

    //java.lang.Exception: Method show04() should not be static 方法shwo04应该没有被static修饰
    //@Test
    public static void show04(){
        System.out.println("Demo02Junit show04方法");
    }

    //java.lang.Exception: Method show05() should be public 方法show05应该是public修饰
    //@Test
    void show05(){
        System.out.println("Demo02Junit show05方法");
    }

    
    @Test
    public void method(){
        show01();
        show02(10);
        String s = show03();
        System.out.println(s);
        show04();
        show05();
    }
}
4.Junit相关注解
package com.itheima.demo01junit;

import org.junit.*;


public class Demo03Junit {
    @Test
    public void show01(){
        System.out.println("show01方法");
    }

    @Test
    public void show02(){
        System.out.println("show02方法");
    }

    @Test
    public void show03(){
        System.out.println("show03方法");
    }

    @Before
    public void before(){
        System.out.println("before方法!");
    }

    @After
    public void after(){
        System.out.println("after方法!");
    }

    @BeforeClass
    public static void beforeClass(){
        System.out.println("beforeClass方法!");
    }

    @AfterClass
    public static void afterClass(){
        System.out.println("afterClass方法!");
    }
}

执行的结果:

beforeClass方法!
before方法!
show01方法
after方法!
before方法!
show02方法
after方法!
before方法!
show03方法
after方法!
afterClass方法!

备注:

Junit常用注解(Junit5.x版本)
* @BeforeEach:用来修饰方法,该方法会在每一个测试方法执行之前执行一次。
* @AfterEach:用来修饰方法,该方法会在每一个测试方法执行之后执行一次。
* @BeforeAll:用来静态修饰方法,该方法会在所有测试方法执行之前执行一次。
* @AfterAll:用来静态修饰方法,该方法会在所有测试方法执行之后执行一次
5.断言
  • 作用
    预测判断某个条件一定成立, 如果条件不成立,则直接奔溃(抛出断言异常)

  • 使用方式
    两个参数: 第一个代表预判值, 第二个代表实际结果
    如果预判正确就会绿色通过
    如果预判错误就会红色失败
    Assert.assertEquals(期望结果 , 实际结果);

package com.itheima.demo01junit;

import org.junit.Assert;


public class Demo04Junit {
    public static void main(String[] args) {
        //断言正常:程序正常执行
        Assert.assertEquals(true,"aaa".length()==3);
        //断言错误:AssertionError: expected: but was: 预期是true,得到的是false
        //Assert.assertEquals(true,"aaaa".length()==3);

        //断言正常:程序正常执行
        Assert.assertEquals(10,Integer.parseInt("10"));
        //断言错误:AssertionError: expected:<10> but was:<11> 预期是10,得到的是11
        //Assert.assertEquals(10,Integer.parseInt("11"));
    }
}
第二章 网络编程入门

网络编程三要素:协议,IP地址,端口号

1.软件结构

C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。
B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。

两种架构各有优势,但是无论哪种架构,都离不开网络的支持。网络编程,就是在一定的协议下,实现两台计算机的通信的程序。

2.网络通信协议

协议就是规则:就是计算机通信需要遵守的

udp:面向无连接的协议,通信的双方不用建立连接,可以直接发送数据

​ 好处:效率高(速度快),耗资小

​ 弊端:不安全,容易丢失数据

tcp:面向连接协议,客户端和服务器端必须经过3次握手建立逻辑连接,才能通信

​ 好处:安全

​ 弊端:效率低

三次握手:TCP协议中,在发送数据的准备阶段,客户端与服务器之间的三次交互,以保证连接的可靠。

​ 第一次握手,客户端向服务器端发出连接请求,等待服务器确认。服务器你死了吗?

​ 第二次握手,服务器端向客户端回送一个响应,通知客户端收到了连接请求。我活着 啊!!

​ 第三次握手,客户端再次向服务器端发送确认信息,确认连接。我知道了!!

3.IP地址

IP地址:就相当于计算机的身份号(唯一)

ip地址的作用:具有唯一性,在网络中可以通过ip地址找到另外一台计算机
ip地址分类
1.ipv4:ip地址由4个字节组成,一个字节8位(比特位1,0)
    二进制:11001101.11001100.11000001.11001111
    为了表示方便使用十进制:192.0.0.106
    每个字节的范围:0-255(2^8),ip地址第一位不能为0   
    ip地址的数量:42亿
    	2^32=4294967296个
    问题:随着计算机的增多,ip地址面临枯竭(全球IPv4地址在2011年2月分配完毕)不够用,就出了ipv6地址	
2.ipv6:ip地址由16个字节组成,一个字节8位(比特位1,0)
    ip地址的数量:
		2^128=3.4028236692093846346337460743177e+38
        3400000000000000000000000000000000000000000000000000000000000000    
    号称可以为地球上每一粒沙子编写一个ip地址
    为了表示方便使用十六进制:fe80::a8a6:b83c:8b8b:2685%17
常用一些dos命令:dos窗口  win+r==>cmd==>dos窗口     
1.ipconfig	Windows IP 配置
   连接特定的 DNS 后缀 . . . . . . . :
   本地链接 IPv6 地址. . . . . . . . : fe80::a8a6:b83c:8b8b:2685%17
   IPv4 地址 . . . . . . . . . . . . : 192.168.0.106
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 192.168.0.1
2.ping ip地址:测试你的电脑和指定ip地址的电脑是否可以连通
	ping空格ip地址
	C:UsersAdministrator>ping 192.168.0.222  没有ping通
    正在 Ping 192.168.0.222 具有 32 字节的数据:
    来自 192.168.0.106 的回复: 无法访问目标主机。
    来自 192.168.0.106 的回复: 无法访问目标主机。
    来自 192.168.0.106 的回复: 无法访问目标主机。
    来自 192.168.0.106 的回复: 无法访问目标主机。
    C:UsersAdministrator>ping 192.168.0.107  ping通
    正在 Ping 192.168.0.107 具有 32 字节的数据:
    来自 192.168.0.107 的回复: 字节=32 时间=3ms TTL=64
    来自 192.168.0.107 的回复: 字节=32 时间=3ms TTL=64
    来自 192.168.0.107 的回复: 字节=32 时间=5ms TTL=64
    来自 192.168.0.107 的回复: 字节=32 时间=3ms TTL=64
    C:UsersAdministrator>ping www.baidu.com
    正在 Ping www.a.shifen.com [61.135.169.121] 具有 32 字节的数据:
    来自 61.135.169.121 的回复: 字节=32 时间=6ms TTL=56
    来自 61.135.169.121 的回复: 字节=32 时间=4ms TTL=56
    来自 61.135.169.121 的回复: 字节=32 时间=4ms TTL=56
    来自 61.135.169.121 的回复: 字节=32 时间=4ms TTL=56 
    ping 127.0.0.1    ping localhost ping本机的ip地址(你自己电脑的ip地址) 
4.端口号

注意:每个网络软件都会分配一个端口号,通过这个端口号就可以找到这个软件

5.InetAddress类
package com.itheima.demo02InetAddress;

import java.net.InetAddress;
import java.net.UnknownHostException;


public class Demo01InetAddress {
    public static void main(String[] args) throws UnknownHostException {
        show02();
    }

    
    private static void show02() throws UnknownHostException {
        //InetAddress inet = InetAddress.getByName("LAPTOP-8I2VG167");//LAPTOP-8I2VG167/192.168.136.48
        //InetAddress inet = InetAddress.getByName("192.168.136.48");//LAPTOP-8I2VG167/192.168.136.48
        //InetAddress inet = InetAddress.getByName("www.baidu.com");//www.baidu.com/182.61.200.6
        InetAddress inet = InetAddress.getByName("www.itheima.com");//www.itheima.com/47.95.137.221
        System.out.println(inet.getHostAddress());
        System.out.println(inet.getHostName());
        System.out.println(inet);
    }

    
    private static void show01() throws UnknownHostException {
        InetAddress inet = InetAddress.getLocalHost();
        System.out.println(inet);//daofeng/192.168.136.73 打印对象名不是地址,重写了toString方法

        //String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。
        String hostAddress = inet.getHostAddress();
        System.out.println(hostAddress);//192.168.136.73
        //String getHostName() 获取此 IP 地址的主机名。
        String hostName = inet.getHostName();
        System.out.println(hostName);//daofeng
    }
}

第三章 TCP通信程序 1.TCP通信的概述

2.TCP通信的客户端(重点)
package com.itheima.demo03TCP;

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


public class TCPClient {
    public static void main(String[] args) throws IOException {
        //1.创建客户端Socket对象,构造方法绑定服务器的ip地址和端口号(三次握手)
        Socket socket = new Socket("localhost",8888);
        //2.使用Socket对象中的方法getOutputStream,获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //3.使用网络字节输出流OutputStream对象中的方法write,给服务器发送数据
        System.out.println("①客户端给服务器发送数据:你好服务器");
        os.write("你好服务器".getBytes());
        //4.使用Socket对象中的方法getInputStream,获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //5.使用网络字节输入流InputStream对象中的方法read,读取服务器发送的数据
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println("④客户端读取服务器发送的数据:"+new String(bytes,0,len));
        //6.释放资源(Socket)
        socket.close();
    }
}
3.TCP通信服务器端(重点)
package com.itheima.demo03TCP;

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


public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.创建服务器ServerSocket对象,构造方法和系统要指定的端口号
        ServerSocket server = new ServerSocket(8888);
        //2.使用服务器ServerSocket对象中的方法accpet,监听并获取客户端Socket对象
        System.out.println("----------------服务器已经启动,等待客户端连接--------------------");
        Socket socket = server.accept();
        //3.使用Socket对象中的方法getInputStream,获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //4.使用网络字节输入流InputStream对象中的方法read,读取客户端发送的数据
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println("②服务器读取客户端发送的数据:"+new String(bytes,0,len));
        //5.使用Socket对象中的方法getOutputStream,获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //6.使用网络字节输出流OutputStream对象中的方法write,给客户端发送数据
        System.out.println("③服务器给客户端发送数据:收到谢谢");
        os.write("收到谢谢".getBytes());
        //7.释放资源(Socket,ServerSocket)
        socket.close();
        server.close();
    }
}

服务器启动之后,服务器的accpet方法一直处于监听状态,等待客户端连接

4.TCP通信的流程

第四章 综合案例 1.文件上传案例需求分析

2.文件上传的客户端(重点)
package com.itheima.demo04TCPUpload;

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


public class TCPClient {
    public static void main(String[] args) throws IOException {
        //1.创建本地字节输入流FileInputStream对象,构造方法中绑定要读取的数据源
        FileInputStream fis = new FileInputStream("c:\1.jpg");
        //2.创建客户端Socket对象,构造方法中封装服务器ip地址和端口号(3次握手)
        Socket socket = new Socket("127.0.0.1",9999);
        //3.使用Socket对象中的方法getOutputStream,获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //4.使用本地字节输入流FileInputStream对象中的方法read,读取要上传的文件
        byte[] bytes= new byte[1024];
        int len = 0;
        while ((len=fis.read(bytes))!=-1){
            //5.使用网络字节输出流OutputStream对象中的方法write,把读取到的文件上传服务器
            os.write(bytes,0,len);
        }

        
        socket.shutdownOutput();

        //6.使用Socket对象中的方法getInputStream,获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //7.使用网络字节输入流InputStream对象中的read,读取服务器回写的"上传成功!"
        System.out.println("333333333333333333333333333333333");
        while ((len=is.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len));
        }
        System.out.println("444444444444444444444444444444444");
        //8.释放资源(fis,Socket)
        fis.close();
        socket.close();
    }
}
3.文件上传的服务器端(重点)
package com.itheima.demo04TCPUpload;

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


public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.判断d盘是否有upload文件夹,没有则创建
        File file = new File("d:\upload");
        if(!file.exists()){
            file.mkdir();
        }
        //2.创建服务器ServerSocket对象,构造方法和系统要指定的端口号
        ServerSocket server = new ServerSocket(9999);
        //3.使用ServerSocket对象中的方法accpet,监听并获取客户端Socket对象
        System.out.println("--------------服务器已经启动,等待客户端上传文件---------------");
        Socket socket = server.accept();
        //4.使用Socket对象中的方法getInputStream,获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //5.创建本地字节输出流FileOutputStream对象,构造方法中邦迪要写入目的地
        FileOutputStream fos = new FileOutputStream("d:\upload\1.jpg");
        //6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
        byte[] bytes = new byte[1024];
        int len = 0;
        System.out.println("11111111111111111111111111111111111");
        while ((len=is.read(bytes))!=-1){
            //7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上
            fos.write(bytes,0,len);
        }
        System.out.println("2222222222222222222222222222222222222");
        //8.使用Socket对象中的方法getOutputStream,获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写"上传成功!"
        os.write("上传成功!".getBytes());
        //10.释放资源(fos,socket,server)
        fos.close();
        socket.close();
        server.close();
    }
}

问题:客户端没有读取到服务器回写的"上传成功",服务器和客户端都没有执行结束

4.文件上传的阻塞问题(重点)

socket.shutdownOutput();
5.文件上传自定义文件名称命名规则(了解-扩展)
package com.itheima.demo05TCPUpload;

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


public class TCPServer {
    public static void main(String[] args) throws IOException {
        //1.判断d盘是否有upload文件夹,没有则创建
        File file = new File("d:\upload");
        if(!file.exists()){
            file.mkdir();
        }
        //2.创建服务器ServerSocket对象,构造方法和系统要指定的端口号
        ServerSocket server = new ServerSocket(9999);
        //3.使用ServerSocket对象中的方法accpet,监听并获取客户端Socket对象
        System.out.println("--------------服务器已经启动,等待客户端上传文件---------------");
        Socket socket = server.accept();
        //4.使用Socket对象中的方法getInputStream,获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();

        
        String fileName = "itheima"+System.currentTimeMillis()+new Random().nextInt(999999)+".jpg";

        //5.创建本地字节输出流FileOutputStream对象,构造方法中邦迪要写入目的地
        FileOutputStream fos = new FileOutputStream("d:\upload\"+fileName);
        //6.使用网络字节输入流InputStream对象中的方法read,读取客户端上传的文件
        byte[] bytes = new byte[1024];
        int len = 0;
        System.out.println("11111111111111111111111111111111111");
        while ((len=is.read(bytes))!=-1){
            //7.使用本地字节输出流FileOutputStream对象中的方法write,把读取到的文件保存到服务器的硬盘上
            fos.write(bytes,0,len);
        }
        System.out.println("2222222222222222222222222222222222222");
        //8.使用Socket对象中的方法getOutputStream,获取网络字节输出流OutputStream对象
        OutputStream os = socket.getOutputStream();
        //9.使用网络字节输出流OutputStream对象中的方法write,给客户端回写"上传成功!"
        os.write("上传成功!".getBytes());
        //10.释放资源(fos,socket,server)
        fos.close();
        socket.close();
        server.close();
    }
}

6.多线程版本服务器(了解-扩展)
package com.itheima.demo06ThreadUpload;

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


public class TCPServer {
    public static void main(String[] args) throws IOException {
        File file = new File("d:\upload");
        if(!file.exists()){
            file.mkdir();
        }
        ServerSocket server = new ServerSocket(9999);
        System.out.println("--------------服务器已经启动,等待客户端上传文件---------------");

        //1.定义一个死循环.轮询accpet方法,一直获取客户端Socket对象
        while (true){
            Socket socket = server.accept();

            
            System.out.println("当前上传文件的客户端是:"+socket.getInetAddress().getHostAddress());

            //2.有客户端请求服务器,就开启一个新的线程,完成文件上传
            new Thread(()->{
                try {
                    InputStream is = socket.getInputStream();

                    String fileName = "itheima"+System.currentTimeMillis()+new Random().nextInt(999999)+".jpg";

                    FileOutputStream fos = new FileOutputStream("d:\upload\"+fileName);
                    byte[] bytes = new byte[1024];
                    int len = 0;
                    while ((len=is.read(bytes))!=-1){
                        fos.write(bytes,0,len);
                    }
                    OutputStream os = socket.getOutputStream();
                    os.write("上传成功!".getBytes());
                    fos.close();
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        //server.close();
    }
}
7.模拟BS服务器(了解)

模拟网站服务器,使用浏览器访问自己编写的服务端程序,查看网页效果。

案例分析
  1. 准备页面数据,web文件夹。

    
    
    
        
        我的主页
    
    
        

    我的主页

  1. 我们模拟服务器端,ServerSocket类监听端口,使用浏览器访问,查看网页效果
package com.itheima.demo06BSTCP;

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对象,和系统要指定的端口号
        ServerSocket server = new ServerSocket(8080);
        //使用ServerSocket对象accept,监听并获取客户端Socket对象
        Socket socket = server.accept();
        //使用Socket对象中的方法getInputStream,获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //使用字节输入流InputStream对象中的方法read,读取客户端的请求信息
        byte[] bytes = new byte[1024];
        int len = is.read(bytes);
        System.out.println(new String(bytes,0,len));
        //释放资源
        socket.close();
        server.close();
    }
}

http://localhost:8080/day12/web/index.html

代码实现 BS服务器
package com.itheima.demo07BSTCP;

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


public class TCPServer2 {
    public static void main(String[] args) throws IOException {
        //创建ServerSocket对象和系统要指定的端口号
        ServerSocket server = new ServerSocket(8080);
        //使用ServerSocket对象中的方法accpet,监听并获取客户端Socket对象
        Socket socket = server.accept();
        //使用Socket对象获取网络字节输入流InputStream对象
        InputStream is = socket.getInputStream();
        //1.把网络字节输入流InputStream转换为BufferedReader
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        //2.使用BufferedReader中的方法readLine,读取第一行文本
        String s = br.readLine();//"GET /day12/web/index.html HTTP/1.1";
        //3.使用String类的方法split,根据空格截取字符串,返回一个字符串数组
        String[] arr = s.split(" ");
        //4.只要数组的arr[1] "/day12/web/index.html "
        //5.使用String类的方法subString,从1索引开始截取字符串 "day12/web/index.html"
        String path = arr[1].substring(1);
        //6.创建本地字节输入流,根据文件的相对路径,读取文件
        FileInputStream fis = new FileInputStream(path);
        //7.使用网络字节输出流OutputStream,把读取到的文件,发送到客户端显示
        OutputStream os = socket.getOutputStream();

        //增加以下三行代码的目的:告之客户端浏览器,写回的是html类型的文件,让客户端以网页的形式显示文件,而不是文本
        os.write("HTTP/1.1 200 OKrn".getBytes());
        os.write("Content-Type:text/htmlrn".getBytes());
        os.write("rn".getBytes());

        //一读一写复制文件
        byte[] bytes =  new byte[1024];
        int len = 0;
        while ((len=fis.read(bytes))!=-1){
            os.write(bytes,0,len);
        }
        fis.close();
        socket.close();
        server.close();
    }
}

c.index.html页面添加多个图片,多次请求服务器

package com.itheima.demo07BSTCP;

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


public class TCPServer3 {
    public static void main(String[] args) throws IOException {
        //创建ServerSocket对象和系统要指定的端口号
        ServerSocket server = new ServerSocket(8080);

        //1.增加一个死循环,轮询accpet方法,一直监听客户端的请求
        while (true){
            //使用ServerSocket对象中的方法accpet,监听并获取客户端Socket对象
            Socket socket = server.accept();
            //2.有客户端请求服务器,获取到客户端,开启一个新的线程,根据客户端发送的路径,读取文件,给服务器写回
            new Thread(()->{
                try {
                    //使用Socket对象获取网络字节输入流InputStream对象
                    InputStream is = socket.getInputStream();
                    //1.把网络字节输入流InputStream转换为BufferedReader
                    BufferedReader br = new BufferedReader(new InputStreamReader(is));
                    //2.使用BufferedReader中的方法readLine,读取第一行文本
                    String s = br.readLine();//"GET /day12/web/index.html HTTP/1.1";
                    //3.使用String类的方法split,根据空格截取字符串,返回一个字符串数组
                    String[] arr = s.split(" ");
                    //4.只要数组的arr[1] "/day12/web/index.html "
                    //5.使用String类的方法subString,从1索引开始截取字符串 "day12/web/index.html"
                    String path = arr[1].substring(1);
                    System.out.println(path);
                    //6.创建本地字节输入流,根据文件的相对路径,读取文件
                    FileInputStream fis = new FileInputStream(path);
                    //7.使用网络字节输出流OutputStream,把读取到的文件,发送到客户端显示
                    OutputStream os = socket.getOutputStream();

                    //增加以下三行代码的目的:告之客户端浏览器,写回的是html类型的文件,让客户端以网页的形式显示文件,而不是文本
                    os.write("HTTP/1.1 200 OKrn".getBytes());
                    os.write("Content-Type:text/htmlrn".getBytes());
                    os.write("rn".getBytes());

                    //一读一写复制文件
                    byte[] bytes =  new byte[1024];
                    int len = 0;
                    while ((len=fis.read(bytes))!=-1){
                        os.write(bytes,0,len);
                    }
                    fis.close();
                    socket.close();
                } catch (IOException e) {
                    System.out.println("您发送的路径找不到!");
                }
            }).start();
        }
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/277263.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号