http协议介绍+文件的上传和下载
http协议介绍:
HTTP,超文本传输协议,英文全称是Hypertext Transfer Protocol,它是互联网上应用最为广泛的一种网络协议。HTTP是一种应用层协议,它是基于TCP协议之上的请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求;服务器接到请求后,给予相应的响应信息.
请求协议和响应协议
请求协议:
①请求首行:
②请求头信息:客户端告诉服务器我这边的信息
③空行
④请求体:get请求是没有请求体的
响应协议:
①响应首行:HTTP/1.1 200 OK
②响应头信息:Content-Length 服务器返回数据的总大小
③空行
④响应体:服务器返回的数据
get请求和post请求的区别
get请求直接将请求参数暴露在url,不安全+一般用于向服务器请求数据
post请求将请求参数放在请求体里面,安全的+一般用于向服务器提交数据
Http1.0和http1.1的区别
http1.0是非持续连接
Http1.1是长久持续连接
网络七层
应用层:应用程序,用户看的见 http协议
表示层:将人看的懂的转成计算机看的懂
会话层:发起一个连接
传输层:规定传输协议和端口号 tcp协议 udp协议
网络层:规定网络ip ip协议
数据链路层:
物理层:光缆、网线
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.常用的响应码:
代码:文件的上传activity代码
package com.example.day001;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class Main3Activity extends AppCompatActivity {
private Button buttonid;
private static final String TAG = "Main3Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
buttonid = (Button) findViewById(R.id.buttonid);
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},101);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode==101&&grantResults[0]== PackageManager.PERMISSION_GRANTED){
click(buttonid);
}
}
//上传
private void upload() {
String start="--";//起始
String boundary="*****";//分割
String end="\r\n";//结束
String filename = "/mnt/sdcard/uri.txt";
Log.i(TAG, "upload: "+Environment.getExternalStorageDirectory());
try {
URL url = new URL("http://169.254.152.180/test/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.setDoOutput(true);
//设置请求头
connection.setRequestProperty("Connection","Keep-Alive");
connection.setRequestProperty("Content-Type","multipart/form-data;boundary"+boundary);
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
OutputStream outputStream = connection.getOutputStream();
//设置请求头 请求体
StringBuffer sb = new StringBuffer();
sb.append(start+boundary+end);
sb.append("Content-Disposition:form-data;name=\"file\";filename=\""+filename+"\""+end);//文件地址
sb.append("Content-Type:multipart/form-data/"+end);
sb.append(end);//空行
outputStream.write(sb.toString().getBytes());
//写内容
FileInputStream fileInputStream = new FileInputStream(new File(filename));//读那个文件
int len=0;
byte[] b=new byte[1024];
while ((len=fileInputStream.read(b))!=-1){
outputStream.write(new String(b,0,len).getBytes());
}
fileInputStream.close();
//
outputStream.write(end.getBytes());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void click(View view) {
new Thread(){
@Override
public void run() {
super.run();
upload();
}
}.start();
}
}
上传的xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main3Activity">
<Button
android:id="@+id/buttonid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="上传"
android:onClick="click"
/>
</LinearLayout>
文件的下载
下载成功后打开的效果
Activity中的代码
package com.example.day001;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class Main4Activity extends AppCompatActivity {
private ProgressBar pro;
private Button start;
private Button stop;
private int end=0;//结束
private static final String TAG = "Main4Activity";
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==100){
Toast.makeText(Main4Activity.this, "下载完毕", Toast.LENGTH_SHORT).show();
}else if (msg.what==101){
pro.setMax(msg.arg1);//设置进度条最大值的
Log.i(TAG, "handleMessage: "+msg.arg1);
}else if (msg.what==102){
pro.setProgress(msg.arg1);//更新进度
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
pro = (ProgressBar) findViewById(R.id.pro);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
start.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Thread(){
@Override
public void run() {
super.run();
getLength("http://uvideo.spriteapp.cn/video/2019/0512/56488d0a-7465-11e9-b91b-1866daeb0df1_wpd.mp4");
download("http://uvideo.spriteapp.cn/video/2019/0512/56488d0a-7465-11e9-b91b-1866daeb0df1_wpd.mp4");
}
}.start();
}
});
}
//获得文件总长度
public void getLength(String url){
try {
URL url1 = new URL(url);
HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
if (connection.getResponseCode()==200){
end = connection.getContentLength();//这个是文件最大值
//是为了给进度条来设置
Message message = new Message();
message.what=101;
message.arg1=end;
handler.sendMessage(message);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//断点下载-更新进度-分批保存
public void download(String url){
int start=0;//开始
int sum=0;//累积长度
try {
URL url1 = new URL(url);
//真实长度是len,1024
String filepath="/mnt/sdcard"+"/a1705";
Log.i(TAG, "download: "+filepath);
//Fileoutputstream不能分批次写入文件
RandomAccessFile file=new RandomAccessFile(filepath,"rw");
file.seek(start);//0开始
HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
connection.setRequestMethod("GET");
connection.setRequestProperty("Range","bytes="+start+"-"+end);//0-1024下载的范围
if (connection.getResponseCode()==206){//断点下载的正常ok响应码206 普通是200
InputStream inputStream=connection.getInputStream();
int len=0;
byte[] b=new byte[2048];
while ((len=inputStream.read(b))!=-1){
file.write(b,0,len);//写文件内容
sum+=len;//记录是否完成更新进度
Message message = new Message();
message.what=102;
message.arg1=sum;
handler.sendMessage(message);
if (sum==end){
handler.sendEmptyMessage(100);
}
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
文件下载的xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Main4Activity">
<ProgressBar
android:id="@+id/pro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
/>
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始"
/>
<Button
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂停"
/>
</LinearLayout>