【Linux】HTTP超文本传输协议

http主要用在浏览器和web服务器通信,是基于TCP协议的应用层无连接的传输协议。

HTTP与HTTPS

http是明文数据传输,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息。协议使用端口号:80。

https更加安全:数据加密、校验(防止被篡改),建立https网站需要申请ca证书(证明合法性,防止中间人攻击)。协议使用端口号:443

        加密方法:对称+非对称加密+证书+数字签名(对比防止证书被修改)

 对称加密(对加密和解密使用相同密钥的加密算法):RC4、DES、3DES、AES、ChaCha20 等

非对称加密(公钥加密,私钥解密): DH、DSA、RSA、ECC 等。

访问http的网站:

        会被提示不安全。

【Linux】HTTP超文本传输协议_第1张图片

https的网站:

        有一个安全的锁。

​​


HTTP请求

请求头部:

浏览器给服务器发送

每一行结束都有一个\r\n;

头部与数据部分隔一行\r\n,空行表明头部结束了

【Linux】HTTP超文本传输协议_第2张图片

 请求方法:

GET客户端向服务端请求资源,POST客户端向客户端提交数据(如:自己换头像)

其中:GET、HEAD、TRACE、OPTIONS是安全的。【Linux】HTTP超文本传输协议_第3张图片

 应答头部:

服务端给浏览器发

【Linux】HTTP超文本传输协议_第4张图片

 HTTP状态码:

1XX信息,告诉服务器自己还有数据发送;

2XX成功,200 OK;

3XX重定向;

4XX客户端错误;

5XX服务器错误;


 写一个服务端让浏览器使用ip连接 

        这里当服务端接收到浏览器的请求后向其发送:“打印ok?“,但是这是不符合它的应答格式的,此时浏览器无法解析,将其应答直接显示出来

        并且接收信息发送后就关闭了,这种为短链接。

头文件:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

 创建套接字:

int socket_init()
{
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	assert(sockfd!=-1);
	
	struct sockaddr_in saddr;
	memset(&saddr,0,sizeof(saddr));
	saddr.sin_family=AF_INET;
	saddr.sin_port = htons(80);
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    assert(res!=-1);

	res = listen(sockfd,5);
    assert(res!=-1);
    return sockfd;
}

主函数:

        服务器收到浏览器请求后返回一个"打印ok?"

int main()
{
    int sockfd=socket_init();
    assert(sockfd!=-1);

    while(1)
    {
        struct sockaddr_in  caddr;
        int len = sizeof(caddr);
        int c = accept(sockfd,(struct sockaddr*)&caddr,&len);
        if(c<0)continue;

        char buff[1024] = {0};
        int n=recv(c,buff,1023,0);
        if(n<=0)
        {
            close(c);
            continue;
        }

        printf("%s\n",buff);
        send(c,"打印ok?",7,0);
        close(c);
    }
}

申请1024大小的数组必须用管理员权限运行(不然不会分配这么多空间):

服务端可以收到发送请求的浏览器、系统的型号等等

这些数据都存在接收(recv)的buff中。

【Linux】HTTP超文本传输协议_第5张图片

GET请求资源:

【Linux】HTTP超文本传输协议_第6张图片

浏览器指定文件路径,GET后面的与浏览器上输入的东西一样,即把请求送给服务器。

【Linux】HTTP超文本传输协议_第7张图片


让服务器回复指定数据:

        由于请求报文可以得到浏览器申请的数据文件地址,我们可以获取它,然后回一个应答报文。

头文件:

因为要打开文件,所以要加上fcntl.h

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include
//当前程序的位置
#define PATH "/home/stu/day21"

创建套接字:

int socket_init()
{
	int sockfd = socket(AF_INET,SOCK_STREAM,0);
	assert(sockfd!=-1);
	
	struct sockaddr_in saddr;
	memset(&saddr,0,sizeof(saddr));
	saddr.sin_family=AF_INET;
	saddr.sin_port = htons(80);
    saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
    assert(res!=-1);

	res = listen(sockfd,5);
    assert(res!=-1);
    return sockfd;
}

获取文件名:

//获取文件名(Get后面的东西)
char * get_filename(char buff[])//报头存在buff中
{
    char*s = strtok(buff," ");//分割出请求方法
    if(s==NULL)return NULL;
    printf("请求方法:%s\n",s);
    
    s = strtok(NULL," ");//分出文件名
    return s;
}

主函数:

recv,拼接应答报文

默认的主页为index html

int main()
{
    int sockfd=socket_init();
    assert(sockfd!=-1);

    while(1)
    {
//接收数据
        struct sockaddr_in  caddr;
        int len = sizeof(caddr);
        int c = accept(sockfd,(struct sockaddr*)&caddr,&len);
        if(c<0)continue;
//存请求
        char buff[1024] = {0};
        int n=recv(c,buff,1023,0);
        if(n<=0)
        {
            close(c);
            continue;
        }
//打印请求
        printf("%s\n",buff);
//获取浏览器指定的文件名
        char* filename = get_filename(buff);
        if(filename==NULL)
        {
            close(c);//解析不了,直接关闭
            continue;
        }
//拼接http应答报文
        //PATH是自己定义的宏表示当前文件位置,下面要将文件名加到当前路径后
        char path[236] = {PATH};
        if(strcmp(filename,"/")==0)//filename只有一个/表示没有指定文件
        {
            strcat(path,"/index.html");// "/home/stu/day21/index.html"
        }
        else
        {
            strcat(path,filename);
        }
        //获取文件大小
        int fd = open(path,O_RDONLY);
        if(fd==-1)//文件没打开
        {
            close(c);
            continue;
        }
        int size = lseek(fd,0,SRRK_END);   //大小等于文件头到文件末尾的位置     
        lseek(fd,0,SEEK_SET);//再把偏移量移到文件头

        char head[128] = {"HTTP/1.1 200 0K\r\n"};
        strcat(head,"Server: myhttp\r\n");
//将内容格式化输出到一个buff中
        sprintf(head+strlen(head),"Content-Length: %d\r\n",size);
        strcat(head,"\r\n");//空行


//输出头部 
        printf("\n%s",head);
//给客户端发送头部
        send(c,head,strlen(head),0);
//给客户端发送数据
        char data[1024]={0};
        int num = 0;
        while((num=read(fd,data,1024))>0)//读数据
        {
            send(c,data,num,0);//发送
        }
        close(fd);
        close(c);
    }
}

html文件   

        把这个文件放在浏览器申请的文件夹中,服务器可以把它发给浏览器。


    
        
        c2202的主页
    

        
            欢迎
        

 

你可能感兴趣的:(Linux,http,网络,服务器,linux,c++)