HTTP协议(Hyper Text Transfer Protocol,超文本传输协议),是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。HTTP基于客户端/服务端(C/S)架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。它是互联网上应用最为广泛的一种网络协议。HTTP是一种应用层协议,它是基于TCP/IP协议之上的请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求;服务器接到请求后,给予相应的响应信息。
HTTP请求由请求行、请求头、请求体三部分组成:
1.请求行:包括请求方式Method、资源路径URL、协议版本Version;
①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE。
②为请求对应的URL地址,它和报文头的Host属性组成完整的请求URL。
③是协议名称及版本号。
2.请求头:包括一些访问的域名、用户代理、Cookie等信息;
④是HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。与缓存相关的规则信息,均包含在header中
首部字段名有如下:
Accept 指定客户端能够接收的内容格式类型
Accept-Language 指定客户端能够接受的语言类型
Accept-Ecoding 指定客户端能够接受的编码类型
User-Agent 用户代理,向服务器说明自己的操作系统、浏览器等信息
Connection 是否开启持久连接(keepalive)
Host 服务器域名
…
3.请求体:就是HTTP请求的数据。
1.响应行:
①报文协议及版本;
②状态码及状态描述;
2.响应头:
③响应报文头,也是由多个属性组成;
首部字段名如下:
Server 服务器软件名,Apache/Nginx
Date 服务器发出响应报文的时间
Last-Modified 请求资源的最后的修改时间
…
3.响应体:
④响应报文体,即我们真正要的“干货”
响应状态码
1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急…
2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息.
3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。
常见状态码及含义:
200—OK/请求已经正常处理完毕
301—/请求永久重定向
302—/请求临时重定向
304—/请求被重定向到客户端本地缓存
400—/客户端请求存在语法错误
401—/客户端请求没有经过授权
403—/客户端的请求被服务器拒绝,一般为客户端没有访问权限
404—/客户端请求的URL在服务端不存在
500—/服务端永久错误
503—/服务端发生临时错误
HTTP/0.9
HTTP协议的最初版本,功能简陋,仅支持请求方式GET,并且仅能请求访问HTML格式的资源。
HTTP/1.0
在0.9版本上做了进步,增加了请求方式POST和HEAD;不再局限于0.9版本的HTML格式,根据Content-Type可以支持多种数据格式,即MIME多用途互联网邮件扩展,例如text/html、image/jpeg等;同时也开始支持cache,就是当客户端在规定时间内访问统一网站,直接访问cache即可。
但是1.0版本的工作方式是每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keepalive。
HTTP/1.1
解决了1.0版本的keepalive问题,1.1版本加入了持久连接,一个TCP连接可以允许多个HTTP请求; 加入了管道机制,一个TCP连接同时允许多个请求同时发送,增加了并发性;新增了请求方式PUT、PATCH、DELETE等。
但是还存在一些问题,服务端是按队列顺序处理请求的,假如一个请求处理时间很长,则会导致后边的请求无法处理,这样就造成了队头阻塞的问题;同时HTTP是无状态的连接,因此每次请求都需要添加重复的字段,降低了带宽的利用率。
HTTP/2.0
为了解决1.1版本利用率不高的问题,提出了HTTP/2.0版本。增加双工模式,即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,解决了队头堵塞的问题;HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此在2.0版本中将所有的信息字段建立一张表,为表中的每个字段建立索引,客户端和服务端共同使用这个表,他们之间就以索引号来表示信息字段,这样就避免了1.0旧版本的重复繁琐的字段,并以压缩的方式传输,提高利用率。
另外也增加服务器推送的功能,即不经请求服务端主动向客户端发送数据。
当前主流的协议版本还是HTTP/1.1版本。
1.get请求和post请求的区别
get请求直接将请求参数暴露在url,不安全+一般用于向服务器请求数据
post请求将请求参数放在请求体里面,安全的+一般用于向服务器提交数据
2.网络七层
应用层:应用程序,用户看的见 http协议
表示层:将人看的懂的转成计算机看的懂
会话层:发起一个连接
传输层:规定传输协议和端口号 tcp协议 udp协议
网络层:规定网络ip ip协议
数据链路层:
物理层:光缆、网线
3.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协议中预留给能够将连接改为管道方式的代理服务器。
上传文件:post请求
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/jpeg或者image/png
空行
package com.example.download;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
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;
public class shangchuan extends AppCompatActivity {
Button button;
String url="http://169.254.113.244/1705hfs/";
String filname="axiba.jpg";
String path="/sdcard/zha.jpg";
@SuppressLint("HandlerLeak")
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==101){
Toast.makeText(shangchuan.this, "完事儿", Toast.LENGTH_SHORT).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shangchuan);
button=findViewById(R.id.shangchuan);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new shanchuan(url,filname,path,handler).start();
}
});
}
class shanchuan extends Thread{
String url;
String filname;
String path;
Handler handler;
public shanchuan(String url, String filname, String path, Handler handler) {
this.url = url;
this.filname = filname;
this.path = path;
this.handler = handler;
}
@Override
public void run() {
super.run();
URL url1 = null;
try {
url1 = new URL(url);
HttpURLConnection urlConnection = (HttpURLConnection) url1.openConnection();
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/jpg" + "\r\n");
sb.append("\r\n");
byte[] bytes = sb.toString().getBytes("UTF-8");
urlConnection.setRequestProperty("Content-Length",bytes.length+new File(path).length()+"");
urlConnection.setRequestProperty("Content-Type","multipart/form-data; boundary=7e324741816d4");
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
OutputStream outputStream = urlConnection.getOutputStream();
FileInputStream fileInputStream = new FileInputStream(path);
outputStream.write(bytes);
byte[] bytes1=new byte[1024];
int len=0;
while((len=fileInputStream.read(bytes1))!=-1){
outputStream.write(bytes1,0,len);
}
if (urlConnection.getResponseCode() == 200) {
handler.sendEmptyMessage(101);
}
} catch (MalformedURLException e) {
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
package com.example.download;
import android.os.Handler;
import android.os.Message;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class DownLoadThread extends Thread{
private String str_url;
private String path;
private Handler handler;
public DownLoadThread(String str_url, String path, Handler handler) {
this.str_url = str_url;
this.path = path;
this.handler = handler;
}
@Override
public void run() {
super.run();
try {
URL url=new URL(str_url);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(5*1000);
urlConnection.setConnectTimeout(5*1000);
urlConnection.connect();
if(urlConnection.getResponseCode()==200){
int max = urlConnection.getContentLength();
Message message = Message.obtain();
message.what= MainActivity.BAR_MAX;
message.obj=max;
handler.sendMessage(message);
InputStream inputStream = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream(path);
byte[] bytes=new byte[1024];
int len=0;
int count=0;
while ((len=inputStream.read(bytes))!=-1){
fileOutputStream.write(bytes,0,len);
count+=len;
Message message1 = Message.obtain();
message1.what=MainActivity.BAR_CURRENT;
message1.obj=count;
handler.sendMessage(message1);
}
handler.sendEmptyMessage(103);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.example.download;
import android.os.Handler;
import android.os.Message;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class DuandianThread extends Thread {
private String str_url;
private String path;
private Handler handler;
public DuandianThread(String str_url, String path, Handler handler) {
this.str_url = str_url;
this.path = path;
this.handler = handler;
}
@Override
public void run() {
super.run();
int end = 0;
int start = 0;
try {
URL url = new URL(str_url);
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();
}
try {
URL url = new URL(str_url);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
File file = new File(path);
if(file.exists()){
start= (int) file.length();
if(start==end){
handler.sendEmptyMessage(104);
}
}
urlConnection.setRequestProperty("Range","bytes="+start+"-"+end);
if(urlConnection.getResponseCode()==206){
InputStream inputStream = urlConnection.getInputStream();
RandomAccessFile randomAccessFile= new RandomAccessFile(path,"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();
}
}
}