http
http协议是一种超文本协议,它在应用层通过TCP协议来实现其功能。它的端口号为80号端口
当一个浏览器向服务器端请求链接时,首先会进行三次握手。建立链接后浏览器会给服务器发送一个http报文,服务器也会回给浏览器一个http报文。
假设客户端在浏览器中输入“www.baidu.com”,通过dns可以找到输入网址(域名)对应的IP地址
服务器:从硬件上来讲是一台电脑,从软件上来讲是一个进程(程序)
浏览器向服务器发送一个(http)的请求报文,结构如下:
方法:请求的资源(网页)+版本号
客户端名字
主机名字
链接(的长短)
常见的请求资源的方法有以下9中:
服务端回复给客户端的http报文如下:
版本号+状态码信息
服务端名字
文档总长度
文档类型(text是主文档类型,html是子文档类型,text/html代表index.html是text类型中的html文档)
常见的错误如下:
接下来会写一个服务端的代码和资源文件来模拟:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>//套接字头文件
#include <pthread.h>//创建线程的头文件
#include <fcntl.h>//代开文件所用的头文件
void* thread_fun(void* arg)
{
int c=(int)arg;//得到信号量地址将其转换成int*类型
char http_cbuff[512]={0};//定义一个http_cbuff,512个大小的空间
int n=recv(c,http_cbuff,511,0);//接受最多511个数据
if(n<=0)//失败就退出
{
pthread_exit(NULL);
}
printf("read:\n%s\n",http_cbuff);
char *ptr=NULL;//strtok_r分割数据
char *s=strtok_r(http_cbuff," ",&ptr);//按照空格划分
if(s==NULL)
{
close(c);
pthread_exit(NULL);
}
printf("方法:%s\n",s);///打印出方法类型
s=strtok_r(NULL," ",&ptr);
if(s==NULL)
{
close(c);
pthread_exit(NULL);
}
char path[128]={0};//定义一个path空间用来存放报头
if(strcmp(s,"/")==0)//客户端没有给出名字,这时只有一个‘/’
{
strcpy(path,"index.html");//默认为index_html
}
else
{
strcpy(path,".");//根目录
strcat(path,s);//将路径加到后面
}
int fd=open(path,O_RDONLY);//打开文件
if(fd==-1)
{
close(c);//404,找不到资源
pthread_exit(0);
}
int size=lseek(fd,0,SEEK_END);//计算文件的大小
lseek(fd,0,SEEK_SET);//将其置回,否则文件将会直接读到末尾
char http_head[256]={0};
strcpy(http_head,"HTTP/1.1 200 OK\r\n");
strcat(http_head,"server:myhttpd\r\n");
sprintf(http_head+strlen(http_head),"Contene_length:%d\r\n",size);
//从前两行后面写入
strcat(http_head,"\r\n");//头部和数据直接还有一行空行
send(c,http_head,strlen(http_head),0);
//先发送头部
char http_data[512]={0};
int num=-1;
while((num=read(fd,http_data,512))>0)//后发送数据部分
{
send(c,http_data,num,0);
}
close(fd);
close(c);
pthread_exit(NULL);
}
int create();
int main()
{
int sockfd=create();//得到套接字id
assert(sockfd != -1);//断言不为-1
while( 1 )
{
//客户端套接字
struct sockaddr_in caddr;//定义sockaddr_in结构
int len=sizeof(caddr);//计算cadd的大小
int c=accept(sockfd,(struct sockaddr*)&caddr,&len);//accept等待客户端连接,将sockaddr指向sockaddr_in
if(c<0)
{
continue;
}
pthread_t id;//创建一个线程id
pthread_create(&id,NULL,thread_fun,(void*)c);//创建线程,每次进行连接,就用线程来进行处理
//因为线程是以void*类型void*返回值,所以在这里直接把c强转成void*
}
}
int create()//首先创建一个流失套接字
{
int sockfd=socket(AF_INET,SOCK_STREAM,0);//创建套接字
assert(sockfd != -1);//判断不为-1
struct sockaddr_in saddr;//定义sockaddr_in结构
saddr.sin_family=AF_INET;//地址族
saddr.sin_port=htons(80);//端口号
saddr.sin_addr.s_addr=inet_addr("127.0.0.1");//ip地址
int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//绑定,将sockaddr指向sockaddr_in
assert(res != -1);//判断不为-1
listen(sockfd,5);//监听是否有客户端发送请求
return sockfd;//将套接字id返回
}
资源文件如下:
<html>
<title>新页面</title>
<body>
<center>
<h1>欢迎!
<body>
</html>
https
https简单来说就是一种更加安全的http,或者说是对http的一种优化。
我们知道http是一种明文传输,如果黑客截取了服务器和客户端之间的传输报文,就可以直接读取报文中的信息。想象一下,如果我们在网站上输入自己的银行卡和密码,在传输的过程中被黑客截取,那么损失是不可估量的。
SSL
为了最大程度上解决这一问题,网景公司设计了SSL协议专门用来对http协议传输的数据进行加密处理,也就是https。所以https也可以理解为是http+SSL
SSL协议在传输层对网络连接进行加密,用来防止数据在传输过程中不被黑客窃取,SSL协议也已经成为了全球化的标准协议。
SSL协议主要有以下三点功能:
1.对客户端和服务端进行认证。
2.对数据进行加密处理
3.维护数据的完整性,确保数据在传输过程中不被改变
认证流程:
1.客户端向服务端发起新的连接
2.服务端会根据客户端发的数据来考虑是否要对齐进行生成新的钥匙
3.客户端更具服务端的回复信息来产生一个密钥,并用服务器的公开密钥加密后传给服务器
4.服务端返还一个密钥认证信息,以此让客户端来认证服务端
总结一下http和https的主要区别:
1.https协议需要花费一定的费用来获取到SSL的证书用来加密
2.http是超文本协议,信息是透明的。https是进行加密过后的协议,需要进行解密才能读取信息
3.二者痛的端口号不同,http使用的是80号端口,https使用的是443号端口
4.http链接比较简单,https进行连接时需要进行加密传输,身份认证