1704B第21天http协议介绍+文件的上传和下载

第1天http协议介绍+文件的上传和下载

    • 一. http协议介绍:
    • 二.请求协议和响应协议
    • 三.使用fiddler进行http抓包工具查看 详细信息 :该软件以后经常用到
    • 四.http请求协议
    • 五.http响应协议
    • 六.面试必问
      • 1.get请求和post请求的区别
      • 2.Http1.0和http1.1的区别
      • 3.网络七层
      • 4.7种请求方式:
      • 5.常用的响应码:
    • 七.代码:文件的上传和下载(重点)
      • 0.使用hfs软件做文件服务器
      • 1.文件下载(so easy)
    • 2.文件的上传(还可以,需要设置请求头)
      • 3.断点续传(有点难度)

一. http协议介绍:

1704B第21天http协议介绍+文件的上传和下载_第1张图片
HTTP,超文本传输协议,英文全称是Hypertext Transfer Protocol,它是互联网上应用最为广泛的一种网络协议。HTTP是一种应用层协议,它是基于TCP协议之上的请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求;服务器接到请求后,给予相应的响应信息

二.请求协议和响应协议

  1. 请求协议:
    ①请求首行:
    ②请求头信息:客户端告诉服务器我这边的信息
    ③空行
    ④请求体:get请求是没有请求体的
  2. 响应协议:
    ①响应首行:HTTP/1.1 200 OK
    ②响应头信息:Content-Length 服务器返回数据的总大小
    ③空行
    ④响应体:服务器返回的数据

三.使用fiddler进行http抓包工具查看 详细信息 :该软件以后经常用到

Fiddler是一个http协议调试代理工具,它能够记录并检查所有你的电脑和互联网之间的http通讯,设置断点,查看所有的“进出”Fiddler的数据(指cookie,html,js,css等文件)。 Fiddler 要比其他的网络调试器要更加简单,因为它不仅仅暴露http通讯还提供了一个用户友好的格式
1704B第21天http协议介绍+文件的上传和下载_第2张图片

四.http请求协议

①请求首行:
GET /jsp/get.jsp?name=yaotianxue&pass=123456 HTTP/1.1
POST /jsp/post.jsp HTTP/1.1
②请求头信息:客户端告诉服务器我这边的信息
1704B第21天http协议介绍+文件的上传和下载_第3张图片
③空行
④请求体:get请求是没有请求体的,post有请求体
1704B第21天http协议介绍+文件的上传和下载_第4张图片

五.http响应协议

(1)响应首行:HTTP/1.1 200 OK
(2)响应头信息:Content-Length 服务器返回数据的总大小
(3)空行
(4)响应体:服务器返回的数据
1704B第21天http协议介绍+文件的上传和下载_第5张图片

六.面试必问

1.get请求和post请求的区别

get请求直接将请求参数暴露在url,不安全+一般用于向服务器请求数据
post请求将请求参数放在请求体里面,安全的+一般用于向服务器提交数据

2.Http1.0和http1.1的区别

http1.0是非持续连接
Http1.1是长久持续连接

3.网络七层

应用层:应用程序,用户看的见 http协议
表示层:将人看的懂的转成计算机看的懂
会话层:发起一个连接
传输层:规定传输协议和端口号 tcp协议 udp协议
网络层:规定网络ip ip协议
数据链路层:
物理层:光缆、网线

4.7种请求方式:

1、OPTIONS
返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性
2、HEAD
向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
3、GET
向特定的资源发出请求。它本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端。
4、POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。
5、PUT
向指定资源位置上传其最新内容
6、DELETE
请求服务器删除Request-URL所标识的资源
7、TRACE
回显服务器收到的请求,主要用于测试或诊断
8、CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。

5.常用的响应码:

1704B第21天http协议介绍+文件的上传和下载_第6张图片

七.代码:文件的上传和下载(重点)

0.使用hfs软件做文件服务器

1.文件下载(so easy)

public static void download(String url,String path)  {
     
    FileOutputStream fileOutputStream = null;
    InputStream inputStream=null;
    try {
     
        URL url1 = new URL(url);
        HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
        urlConnection.setReadTimeout(5000);
        urlConnection.setConnectTimeout(5000);
        if(urlConnection.getResponseCode()==200){
     
             inputStream = urlConnection.getInputStream();
             fileOutputStream = new FileOutputStream(path);
            //边读边写
            byte[] bytes=new byte[1024];
            int len=0;
            while((len=inputStream.read(bytes))!=-1){
     
                fileOutputStream.write(bytes,0,len);
            }
        }

    } catch (IOException e) {
     
        e.printStackTrace();
    } finally {
     //关流
        if (fileOutputStream != null) {
     
            try {
     
                fileOutputStream.close();
            } catch (IOException e) {
     
                e.printStackTrace();
            }
        }
        if (inputStream != null) {
     
            try {
     
                inputStream.close();
            } catch (IOException e) {
     
                e.printStackTrace();
            }
        }
    }
}

2.文件的上传(还可以,需要设置请求头)

请求协议:首行—头信息-----空行-----请求体
步骤 1.设置请求头信息:
Content-Length:请求体的长度
Content-Type:multipart/form-data; boundary=7e324741816d4
步骤2.设置请求体:2部分
第一部分:要有换行
-----------------------------7e324741816d4
Content-Disposition: form-data; name=“file”; filename=“上传到服务器的名字”
Content-Type: media/mp4或者media/mp3或者image/mp3或者image/png
空行
第二部分:需要上传的文件:边读边写

public class NetUtlis  {
     

    public static void upload(String url,String path,String filname){
     
        URL url1 = null;
        try {
     
            url1 = new URL(url);
            HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
            //TODO 2:设置请求体
            //第一部分
            StringBuffer sb = new StringBuffer();
            sb.append("-----------------------------7e324741816d4"+"\r\n");
            sb.append("Content-Disposition: form-data; name=\"file\"; filename=\""+filname+"\""+"\r\n");
            sb.append("Content-Type: media/mp4" + "\r\n");
            sb.append("\r\n");
            byte[]  bytes = sb.toString().getBytes("UTF-8");
            //TODO 1:请求头信息
            urlConnection.setRequestProperty("Content-Length",bytes.length+new File(path).length()+"");
            urlConnection.setRequestProperty("Content-Type","multipart/form-data; boundary=7e324741816d4");
            //post请求
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoOutput(true);
            OutputStream outputStream = urlConnection.getOutputStream();
            FileInputStream fileInputStream = new FileInputStream(path);
            //TODO 2:发送请求体
            outputStream.write(bytes);//第一次
            byte[] bytes1=new byte[1024];
            int len=0;
            //第二次:从SD卡读取
            while((len=fileInputStream.read(bytes1))!=-1){
     
                outputStream.write(bytes1,0,len);
            }
            if (urlConnection.getResponseCode() == 200) {
     
                System.out.println("上传成功");
            }
        } catch (MalformedURLException e) {
     
        } catch (IOException e) {
     
            e.printStackTrace();
        }
    }
}

3.断点续传(有点难度)

1.设置请求头:
Range:bytes=起始位置-终点位置
比如:Range:bytes=0-100
2.随机访问流:
RandomAccessFile randomAccessFile= new RandomAccessFile(filepath,“rw”);//rw 可读可写
randomAccessFile.seek(start);//从指定位置开始写


public class DuandianActivity extends AppCompatActivity {
     
    Button button;
    ProgressBar bar;
    Handler handler=new Handler(){
     
        @Override
        public void handleMessage(Message msg) {
     
            super.handleMessage(msg);
            if(msg.what==101){
     //总大小
                bar.setMax((Integer) msg.obj);
            }else if(msg.what==102){
     //进度
                bar.setProgress((Integer) msg.obj);
            }else if(msg.what==103){
     
                Toast.makeText(DuandianActivity.this, "下载完毕", Toast.LENGTH_SHORT).show();
            }else if(msg.what==104){
     
                Toast.makeText(DuandianActivity.this, "文件已经存在", Toast.LENGTH_SHORT).show();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
     
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_duandian);
        button=findViewById(R.id.bt_start);
        bar=findViewById(R.id.bar);
        button.setOnClickListener(new View.OnClickListener() {
     
            @Override
            public void onClick(View v) {
     
                new DuanDianThread("http://uvideo.spriteapp.cn/video/2019/0512/56488d0a-7465-11e9-b91b-1866daeb0df1_wpd.mp4","/sdcard/aa.mp4").start();
            }
        });
    }

    class DuanDianThread extends Thread{
     
        private String url_str;
        private String filepath;

        public DuanDianThread(String url_str, String filepath) {
     
            this.url_str = url_str;
            this.filepath = filepath;
        }

        @Override
        public void run() {
     
            super.run();
            int end=0;
            int start=0;
            //TODO  1:第一次连接获取总大小:设置进度条最大值
            try {
     
                URL url = new URL(url_str);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                if(urlConnection.getResponseCode()==200){
     
                    end= urlConnection.getContentLength();
                }
                Message obtain = Message.obtain();
                obtain.what=101;
                obtain.obj=end;
                handler.sendMessage(obtain);
            } catch (MalformedURLException e) {
     
                e.printStackTrace();
            } catch (IOException e) {
     
                e.printStackTrace();
            }


            //TODO 2:第二从连接获得文件的IO流:start---end
            try {
     
                URL url = new URL(url_str);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                //设置请求头信息  stat    end
                File file = new File(filepath);
                if(file.exists()){
     //文件是否存在
                    start= (int) file.length();//开始就是文件的总大小
                    if(start==end){
     

                        handler.sendEmptyMessage(104);
                    }
                }
                urlConnection.setRequestProperty("Range","bytes="+start+"-"+end);
                if(urlConnection.getResponseCode()==206){
     //返回响应码206
                    InputStream inputStream = urlConnection.getInputStream();
                    //随机访问流
                    RandomAccessFile  randomAccessFile=  new RandomAccessFile(filepath,"rw");//rw 可读可写
                    randomAccessFile.seek(start);
                    //边读边写
                    byte[] bytes=new byte[1024];
                    int len=0;
                    int count=start;//已经多少进度了
                    while((len=inputStream.read(bytes))!=-1){
     
                        randomAccessFile.write(bytes,0,len);
                        Thread.sleep(10);
                        count+=len;
                        Message obtain = Message.obtain();
                        obtain.what=102;
                        obtain.obj=count;
                        handler.sendMessage(obtain);
                        if(count==end){
     //下载完毕
                            handler.sendEmptyMessage(103);
                        }
                    }
                }
            } catch (MalformedURLException e) {
     
                e.printStackTrace();
            } catch (IOException e) {
     
                e.printStackTrace();
            } catch (InterruptedException e) {
     
                e.printStackTrace();
            }
        }
    }
}

你可能感兴趣的:(安卓第1个月)