我是靠谱客的博主 俏皮蜜蜂,最近开发中收集的这篇文章主要介绍HTTP协议HTTP协议,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

HTTP协议

14.1 前言

在TCP/IP协议基础上,有很多应用层协议,支持各种网络应用,比如HTTP,SMTP,FTP等等。HTTP协议是最广泛的应用层协议

14.2 通信模型

客户端服务器发起TCP连接http请求报文http响应报文关闭连接客户端服务器
  • 支持客户/服务器模式。

  • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。

  • 灵活:HTTP允许传输任意类型的数据对象。

  • 短连接:无连接的含义是限制每次连接只处理一个请求。

  • 无状态:HTTP协议是无状态协议。

14.3 地址(URL)

URL全称为Unique Resource Location,用来表示网络资源,可以理解为网络文件路径。URL的格式如下:

http://host[":"port][abs_path]

例如:

http://www.xueguoliang.cn:80/ds/index.html

URL的长度有限制,不同的服务器的限制值不太相同,但是不能无限长。以下博文有对RUL长度的一些叙述:
http://www.cnblogs.com/henryhappier/archive/2010/10/09/1846554.html

补充:HTTP协议的服务器和客户端

服务器

Http服务器/Web服务器:apache,nginx,iis(Windows平台)
客户端:浏览器

sudo apt-get install apache2

客户端

curl命令
curl是一个命令行数据传输工具,它支持很多协议,包括DICT, FILE, FTP, FTPS, GOPHER, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, TELNET and TFTP。这里使用curl来学习HTTP协议,因此重点说明HTTP相关的内容。

curl命令格式

curl [option] [URL...]

例如

curl http://www.baidu.com
该命令下载百度主页,并显示在标准输出。

选项[option]

选项长选项解释
-#--progress-bar显示进度条
-d--data, --data-ascii, --data-binarypost协议的数据
-F--form <name=content>提交表单

14.4 HTTP请求

HTTP请求由三部分组成,分别是:请求行、消息报头、请求正文


14.4.1 请求方法

请求行由请求方法字段、URL字段和HTTP协议版本字段3个字段组成,它们用空格分隔。例如:GET /index.html HTTP/1.1

HTTP协议的请求方法有GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT。

而常见的有如下几种:

  • GET

GET方法是HTTP协议中最常见的请求方式,当客户端需要从服务器中读取文档时,往往使用GET方法。GET方法要求服务器URL指定的文档内容。而内容部分,按照HTTP协议规定,放在响应报文的正文部分。

GET方法请求,没有请求正文内容,请求时的参数在URL中携带,由于URL被限制了长度,因此GET方法不适合用于上传数据。同时在浏览器中,通过GET方法来获取网页时,参数会显示在浏览器地址栏上,因此保密性很差。

GET / HTTP/1.1
Host: 192.168.11.80:9889
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:28.0) Gecko/20100101 Firefox/28.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
 
  • POST

POST方法运行客户端给服务器提供比较多的信息。POST方法将请求参数封装在HTTP请求数据中,而且长度没有限制,因为POST携带的数据,在HTTP的请求正文中。

POST /search HTTP/1.1  
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,application/msword, application/x-silverlight, application/x-shockwave-flash, */*  
Referer: <a href="http://www.google.cn/">http://www.google.cn/</a>  
Accept-Language: zh-cn  
Accept-Encoding: gzip, deflate  
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)  
Host: <a href="http://www.google.cn">www.google.cn</a>  
Connection: Keep-Alive  
Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-FxlRugatx63JLv7CWMD6UB_O_r  
 
hl=zh-CN&source=hp&q=domety  
  • HEAD

HEAD只返回信息头,不要求服务器返回URL所指资源内容。

14.4.2 消息报头

消息报头由关键字/值对组成,每行一对,关键字和值用:分割。
比如

Accept-Language: zh-cn  
Accept-Encoding: gzip, deflate

14.4.3 空行

最后一个消息报头和正文之间,是一个空行。GET请求没有正文。

14.4.4 请求正文

请求正文在POST方法中使用。

14.5 HTTP响应

HTTP响应由三部分组成,分别是:状态行、消息报头、响应正文。HTTP响应的格式于请求的格式很类似:

<status-line>
<headers>
<blank line>
[<response-body>]

唯一的区别就是第一行的请求行,变成了状态行。状态行格式举例如下:

HTTP/1.1 200 OK

其中HTTP/1.1表示协议和版本信息,200表示服务器的响应码,OK表示状态码的描述,状态码由3位数组成,第一个数字表示了响应的类别,一共有5种类别。

  • 1xx:表示服务器正在处理

  • 2xx:成功,请求被正确的理解或者处理

  • 3xx:重定向

  • 4xx:客户端错误,客户端的请求,服务器无法理解。

  • 5xx:服务器错误,服务器未能实现的合法请求。

常见的状态码举例:

  • 200 OK:客户端请求成功

  • 400 Bad Request:请求报文有语法错误

  • 401 Unauthorized:未授权

  • 403 Forbidden:服务器拒绝服务

  • 404 Not Found:请求的资源不存在

  • 500 Internal Server Error:服务器内部错误

  • 503 Server Unavailable:服务器临时不能处理客户端请求(稍后可能可以)

响应报文例子:

HTTP/1.1 200 OK
Date: Sat, 05 Nov 2016 08:14:20 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Sat, 05 Nov 2016 08:06:04 GMT
ETag: "d-54089432494fd"
Accept-Ranges: bytes
Content-Length: 13
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
 
 
this is xxx
 

14.6 使用HTTP协议实现通信

服务器的开发不容易,尤其是开发高性能、稳定性好服务器,更加不容易,因此人们尝试更好简单的方式来开发软件。在服务器方面,使用WEB服务器,采用HTTP协议来代替底层的SOCKET,是常见的选择。采用HTTP协议更加除了能得到稳定的服务器支持外,更加可以兼容各种客户端(手机、PC、浏览器)等等。这样实现了一个服务器之后,多个客户端可以通用。

在开发应用程序时,客户端应用程序为了和WEB服务器通信,需要对请求报文进行打包成HTTP请求格式,而服务器响应了HTTP响应报文到客户端之后,也需要对响应报文进行解释。libcurl库,可以完成这些功能。

而Web服务器的选择是多样化的:Apache,nginx,libevent,tufao。一些使用C/C++开发的开源的Http服务器列表在这里:
http://www.oschina.net/project/tag/106?lang=21&os=0&sort=time

通信时,应用程序的通信报文目前采用的json格式较多,也有一些采用xml格式或者http协议规定的表单格式。

补充

客户端:浏览器
服务器:apache + c语言写的CGI程序
实现HTTP通信

CGI技术在早期解决动态网页,和网页跟服务器交互的问题。

  • apache2安装

  • 了解配置
    静态文档位置:/var/www/html
    apache可执行程序:/usr/lib/cgi-bin/

为了支持CGI,需要以下命令支持

cd /etc/apache2/mods-enable
sudo ln -s ../mods-available/cgid.conf
sudo ln -s ../mods-available/cgid.load
sudo ln -s ../mods-available/cgi.load
sudo /etc/init.d/apache2 restart

简单的CGI程序代码案例,编译出的可执行程序,需要在/usr/lib/cgi-bin目录下

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
extern char** environ;
int main()
{
// http协议的规定
// 重定向
printf("Content-type:text/htmlnn");
// 输出环境变量
for(int i=0; ;++i)
{
if(environ[i])
{
//
printf("%s<br>n", environ[i]);

}
else
{
break;
}
}
// 获取环境变量QUERY_STRING的值,获取客户端参数
char* query_string = getenv("QUERY_STRING");
strtok(query_string, "=&");
char* username = strtok(NULL, "=&");
strtok(NULL, "=&");
char* password = strtok(NULL, "=&");
if(strcmp(username, "aa") == 0
&& strcmp(password, "bb") == 0)
{
printf("Login success<br>n");
}
else
{
printf("Login error<br>n");
}
}

 

14.6.1 libcurl

libcurl 官网:https://curl.haxx.se/
libcurl也是curl工具使用的库

  • 下载源码

可以到官网下载,更方便的是到github上克隆代码

git clone https://github.com/curl/curl.git
  • 编译和安装

cd curl
./buildconf
./configure
make
sudo make install

安装完毕之后,头文件
/usr/local/include/curl
/usr/local/lib/libcurl.so
可执行命令
/usr/local/bin/curl

另外一种办法是:可以简单的执行
sudo apt-get install curl
安装curl命令,该命令将curl安装/usr/bin
sudo apt-get install libcurl4-openssl-dev
来安装libcurl,libcurl的安装路径
头文件:/usr/include/curl
库目录:/usr/lib

  • 使用

#include <stdio.h>
#include <curl/curl.h>
bool getUrl(char *filename)
{
CURL *curl;
CURLcode res;
FILE *fp;
if ((fp = fopen(filename, "w")) == NULL)
// 返回结果用文件存储
return false;
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: Agent-007");
curl = curl_easy_init();
// 初始化
if (curl)
{
//curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");// 代理
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);// 改协议头
curl_easy_setopt(curl, CURLOPT_URL,"http://www.baidu.com");
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); //将返回的http头输出到fp指向的文件
curl_easy_setopt(curl, CURLOPT_HEADERDATA, fp); //将返回的html主体数据输出到fp指向的文件
res = curl_easy_perform(curl);
// 执行
if (res != 0) {
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
}
fclose(fp);
return true;
}
}
bool postUrl(char *filename)
{
CURL *curl;
CURLcode res;
FILE *fp;
if ((fp = fopen(filename, "w")) == NULL)
return false;
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt"); // 指定cookie文件
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "&logintype=uid&u=xieyan&psw=xxx86");
// 指定post内容
//curl_easy_setopt(curl, CURLOPT_PROXY, "10.99.60.201:8080");
curl_easy_setopt(curl, CURLOPT_URL, " http://mail.sina.com.cn/cgi-bin/login.cgi ");
// 指定url

curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
fclose(fp);
return true;
}
int main(void)
{
getUrl("/tmp/get.html");
postUrl("/tmp/post.html");
}

 

基本流程是:

  • 初始化CURL环境

  • 创建CURL对象

  • 设置CURL

  • 执行CURL

14.6.2 tufao

tufao是一个由QT编写的HTTP服务器。

tufao代替apache来实现http的通信。

安装tufao

  1. 获取代码

  2. 编译和安装

    • sudo apt-get install cmake qtsdk

    • 在tufao目录下创建build目录

    • cd build

    • cmake .. -DCMAKE_INSTALL_PREFIX=/usr

    • make

    • sudo make install

  3. 创建工程

    • 创建空的工程

    • 工程文件中增加CONFIG += TUFAO1 C++11

    • 增加一个类MyServer,一定是QObject派生类

    • 增加一个main.cpp实现main函数

    • 在MyServer的构造函数,创建Tufao::HttpServer对象server

    • 将server的信号requestReady和自己写的槽函数slotRequestReady连接

    • slotRequestReady函数中,实现http协议的响应报文。

14.6.3 libevent

略。

14.6.4 json

JSON是一种轻量级的数据交换格式,它简洁并且具有很好的可拓展性,容易阅读,也容易被机器解析,因此JSON成为当前最流行的数据交换格式。

JSON格式例子如下:

  • 用JSON来描述一个人的属性。

{
    name: "tom",
    age: 18,
    man: true
}
  • 嵌套对象:

{
    name:"tom",
    age:18,
    mobile:{
        branch: "apple",
        version: 6
    }
}
  • 数组:

{
    name:"tom",
    age:18,
    score:[
        91,
        100,
        78,
        85
    ],
    mobile: null
 
}
  • 根节点为数组

[
    {
        name:"tom",
        age:18,
        man:true
    },
    {
        name:"rose",
        age:18,
        man:false
    }
]

JSON由成对的key: value序列组成。key的类型永远是字符串,而value的类型可以是:

  • 数字:可表示整数或者浮点数

  • boolean:true或者false

  • null:null类型只有null一个值

  • 字符串:

  • 对象:使用{}定义

  • 数组:使用[]定义

各种语言都有JSON的生成和解析的库,C语言使用cJson,C++则更多的使用rapidJson。

14.6.5 xml

略。

14.7 HTTPS安全通信

一般网络通信是不安全的,因为有许多中间设备可能通过类似抓包的技术,可以获取报文,如果报文中携带一些敏感的信息,比如用户名和密码信息。

如果使用对称加密技术,密钥传输的安全性同样值得怀疑,而一旦密钥泄露,加密形同虚设。

非对称加密技术可以使用的加密密钥和解密密钥是不同的,加密密钥不能用于解密,这样加密密钥泄漏了,也不影响数据安全性。这样客户端可以安全得到加密密钥,而其他人得到加密密钥无法解密。

在HTTPS中,客户端随机生成对称的加密密钥,然后通过服务器给的非对称的加密密钥,加密对称的加密密钥,然后发给服务器,后续的通信使用对称机密。

HTTPS技术使得传输过程的安全无懈可击,但是如果认为任何带HTTPS的网站就是安全的那就错了,因为有些钓鱼网站,来骗取用户的敏感信息,因此需要第三方机构来监控提供服务的服务器的安全性。HTTPS证书需要花钱购买,也有一些机构颁发免费的HTTPS证书。

有些更加严格的HTTPS通信,要求客户端也必须有证书。因为别人可以得到加密密钥,就可以实行假冒行为。银行的客户端一般需要证书,而证书保存在银行配的u盘中。

在实际的编码中,HTTPS并不需要增加多少额外的工作,就可以实现HTTPS通信。

14.8 负载均衡

负载均衡技术,可以使得多个服务器分别负担繁重的用户请求。负载均衡可以通过许多技术来实现,比如DNS、NGINX反向代理、LVS、重定向等等。

目前比较流行的有NGINX的反向代理实现负载均衡。

发表于 2018-07-04 14:26 天码丶行满 阅读( ...) 评论( ...) 编辑 收藏
 
刷新评论 刷新页面 返回顶部

最后

以上就是俏皮蜜蜂为你收集整理的HTTP协议HTTP协议的全部内容,希望文章能够帮你解决HTTP协议HTTP协议所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(106)

评论列表共有 0 条评论

立即
投稿
返回
顶部