认识url
平时我们俗称的 “网址” 其实就是说的 URL
url格式
使用 http: 或 https: 等协议方案名获取访问资源时要指定协议类型。不
区分字母大小写,最后附一个冒号(:)。
urlencode和urldecode
像 / : 等这样的字符, 已经被url当做特殊意义理解了. 因此这些字符不能随意出现.
比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义.
转义的规则如下:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY
格式:
“+” 被转义成了 “%2B”
urldecode就是urlencode的逆过程;
HTTP基本特征:
-
无连接:因为HTTP是基于TCP协议,HTTP在通信时并不关心底层是如何通信的,所以因为TCP在底层已经建立好链接了,所以HTTP在通信时并不需要建立连接。TCP建立连接与HTTP无关,http直接向对方发送 HTTP请求即可。
-
无状态:tcp在底层通信时是有状态的,但是这些和http无关,他只关心能不能使用。因为http是给用户使用的,所谓无状态是并不会记录用户的信息,记录信息的技术是cookie + session
-
简单快速:基于短链接的超文本传输http1.0,http1.1长连接
HTTP构成
这是request请求当sever收到时,该如何解析呢?因为协议报头都是以行为单位,当读空行时就读完请求报头,对于sever来说从空行的下一行就是请求正文,但是不知道都多少就结束。任何协议要解决两个问题第一就是将报头和有效载荷分离,但是这只是将包头分离并没有将有效载荷分离。对于有效载荷,在请求报头中有一个Content-Length的属性,就是空行之后有效载荷地有效字节数。
响应读取基本和请求差不多
到底什么是cookie
当client要访问服务器上的资源就要登录,当http通信时,第一次登陆后访问了资源后,当第二次要放问资源因为http是无状态的,所以服务器是不会让他们放问的。这时就要一种技术来记住他们的信息这就有了cookie
当第一次client访问服务器的资源上传自己的用户信息和登录信息服务i其作出相应将登录信息封装到set-cookie发送到client中这个信息以cookie的形式保存在主机当中。所以在浏览器的每次请求中都包cookie信息不用每次都上传信息,当服务器收到请求时自动分析cookie自动对其认证。
cookie:本质就是一个浏览器文件
什么是session
session
用户信息直接保存在cookie中当别人拿到就能直接登录所以是不安全的,所以又有了一个session技术,当client当登录信息上传到服务器完成认证,形成一个sid,该sid是全服务器的唯一一个序列号,服务器把sid和登录信息写道一个session文件中,服务器把set-cookie传输到主机,将sid保存在cookie文件中,当再一次登录是只需将服务器只需用cookie包含的sid找到服务器中所对应地session文件完成认证即可。
利用抓包工具来获取HTTP请求响应
HTTP传输 浏览器先将请求经网络传输到网络,经网络传输到服务器,服务器解析后做出响应,服务器再把响应经网络传输到浏览器。
浏览器先将请求经网络传输到抓包工具,抓包工具再将数据经网络传输到服务器,服务器解析后做出响应这是正向代理。服务器再把响应经网络传输到抓包工具,再传到浏览器,这叫做反向代理。
request
首行: [方法] + [url] + [版本]
Header: 请求的属性, 冒号分割的键值对;每组属性之间使用 分隔;遇到空行表示Header部分结束
Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个Content-Length属性来标识Body的长度;
response
首行: [版本号] + [状态码] + [状态码解释]
Header: 请求的属性, 冒号分割的键值对;每组属性之间使用 分隔;遇到空行表示Header部分结束
Body: 空行后面的内容都是Body. Body允许为空字符串. 如果Body存在, 则在Header中会有一个
Content-Length属性来标识Body的长度; 如果服务器返回了一个html页面, 那么html页面内容就是在body中.
HTTP的方法

HTTP的状态码

HTTP常见Header
简单的HTTP服务器
#include<iostream>
#include<sys/wait.h>
#include<netinet/in.h>
#include<cstdio>
#include<sys/types.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<cstdlib>
#include<sys/socket.h>
using namespace std;
class sever{
private:
int listen_sock;//监听套接字
int post;
public:
sever(int post_){
post=post_;
}
void Init(){
listen_sock=socket(AF_INET,SOCK_STREAM,0);
if(listen_sock<0){
cout<<"套接字创建失败!"<<endl;
exit(0);
}
struct sockaddr_in addr;
addr.sin_family=AF_INET;
addr.sin_port=htons(post);
addr.sin_addr.s_addr=INADDR_ANY;
if(bind(listen_sock,(struct sockaddr*)&addr,sizeof(addr))<0){
cout<<"绑定失败!"<<endl;
exit(1);
}
if(listen(listen_sock,5)<0){
cout<<"绑定失败!"<<endl;
exit(2);
}
}
void star(){
while(1){
struct sockaddr_in in_addr;
socklen_t len=sizeof(in_addr);
int sock=accept(listen_sock,(struct sockaddr*)&in_addr,&len);
if(sock<0){
cout<<"获取链接失败!"<<endl;
continue;
}
char s1[16];
sprintf(s1,"%d",ntohs(in_addr.sin_port));
string IP_PORT=inet_ntoa(in_addr.sin_addr);
IP_PORT+=":";
cout<<"get a new link"<<IP_PORT<<s1<<endl;
int id=fork();
if(id==0){
close(listen_sock);
service(sock);
exit(0);
}
close(sock);
// waitpid(-1,NULL,0);
}
}
void service(int sock){
signal(SIGCHLD,SIG_IGN);//线程分离
char buff[1024*2];
int s=recv(sock,buff,sizeof(buff),0);
if(s>0){
buff[s]=0;
cout<<buff<<endl;
string response="HTTP/1.0 200 OK
";
response+="Content-type: text/html
";
response+="
";
response+="
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>helloword</title>
</head>
<body>
<h1>hello word</h1>
</body>
</html> ";
send(sock,response.c_str(),response.size(),0);
}
close(sock);
}
~sever(){
close(listen_sock);
}
};
int main(int argc,char*argv[]){
sever s(atoi(argv[1]));
s.Init();
s.star();
}
编译, 启动服务. 在浏览器中输入 http://[ip]:[port], 就能看到显示的结果 “Hello World”

HTTP vs HTTPS
对称加密
对称加密过程如下:
那么密钥怎么让server知道呢?
如果直接传输也无法实现加密效果,也就无法实现安全加密。这就有了非对称加密.
非对称加密
通常公钥是用来加密地,私钥是用来解密的
https:密钥协商过程 server->公钥->client对称秘钥,用公钥加密->server->私钥解密拿到对称密钥,可以对称加密通信了
看一个场景:
一个黑客在client和server加一个中间服务器,这个中间服务器有自己的公钥私钥和对称密钥。中间服务器将client中的server公钥换成中间服务器的公钥,client将通信用的对称密钥发送给中间服务器,这样client和中间服务器中间进行数据交换。同样server之间也能这杨也能通信,当client想把数据传输给server但是中间经过了中间服务器,这给信息就泄露了,也可能被篡改了。所以在通信时要对远端服务器进行身份认证。
问题:
中间信息被篡改问题?
这个文本只要稍微改变一下这个字符序列就会改变所以新字符序列不等于字符序列。所以通过数据摘要可以得知文本有没有改变
对于黑客来说可能数据摘要可能也被改变,所以在传输数据摘要是需要用对称密钥将数据摘要加密,加密地数据摘要叫做数据签名(指纹)。
远端服务器身份识别问题?