Day1:http协议介绍+文件的上传和下载

一. http协议介绍:

在这里插入图片描述
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通讯还提供了一个用户友好的格式
在这里插入图片描述

四.http请求协议

①请求首行:
GET /jsp/get.jsp?name=yaotianxue&pass=123456 HTTP/1.1
POST /jsp/post.jsp HTTP/1.1
②请求头信息:客户端告诉服务器我这边的信息
在这里插入图片描述
③空行
④请求体:get请求是没有请求体的,post有请求体
在这里插入图片描述

五.http响应协议

(1)响应首行:HTTP/1.1 200 OK
(2)响应头信息:Content-Length 服务器返回数据的总大小
(3)空行
(4)响应体:服务器返回的数据
在这里插入图片描述

六.常见的请求头和响应头

https://www.cnblogs.com/s313139232/p/7830983.html

七.面试必问

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

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

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

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

3.网络七层

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

4.8种请求方式:

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.常用的响应码:

在这里插入图片描述

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

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)请求头:

在这里插入图片描述

(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/jpg或者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();
            }
        }
    }
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值