25-LINUX--HTTP协议与web服务器

一.浏览器与服务器的通信过程

        浏览器与web服务器在应用层通信使用的是HTTP协议(超文本传输协议),是可靠的协议。而HTTP协议在传输层使用的是TCP协议,浏览器和web服务器三次握手建立连接后,才可以发送HTTP请求报文,服务器在收到请求报文后,向浏览器回复HTTP应答报文。

        浏览器在向服务器发起连接前,需要得到服务器的IP和端口。用户在浏览器中只需要输入网址,浏览器会通过DNS服务查询获取到的服务器的IP地址,对于服务器来讲,使用HTTP协议的一般是80端口。

        浏览器和服务器建立连接后,如果两次以上的请求重复使用一个TCP连接,我们称之为长连接。如果浏览器发送一次请求报文,服务器回复一次就断开连接,下次交互需要重新三次握手建立连接的,我们称之为短链接。

        常见的web服务器有:

                1.Apache:简单、速度快,性能稳定。可做代理服务器使用

                2.IIS(Internet Information Server):安全性、强大、灵活

                3.Nginx:小巧而高效,可以做高效的负载均衡反向代理

                4.Tomcat:技术先进、性能稳定、免费

二.HTTP请求报头

1.HTTP请求报头结构

2.请求方法

        1>.GET 申请获取资源,而不对服务器产生任何其他影响
        2>.HEAD 和 GET 方法类似,不过仅要求服务器返回头部信息,而不需要传输任何实际内容
        3>.POST 客户端向服务器提交数据的方法。这种方法会影响服务器:服务器可能根据收到的数据动态创建新的资源,也可能更新原有的资源
        4>.PUT 上传某个资源
        5>.DELETE 删除某个资源
        6>.TRACE 要求目标服务器返回原始 HTTP 请求的内容。它可用来查看中间服务器(比如代理服务器)对 HTTP 请求的影响
        7>.OPTIONS 查看服务器对某个特定 URL 都支持哪些请求方法。也可以把 URL 设置为 *,从而获得服务器支持的所有请求方法
        8>.CONNECT 用于某些代理服务器,它们能把请求的连接转化为一个安全隧道
        9>.PATCH 对某个资源做部分修改

3.应答报头结构

4.应答状态

三.代码

1.HTTP代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <fcntl.h>

#define  PATH "/home/stu/桌面/c2305/day21"
int socket_init();
char* get_filename(char buff[])
{
    char*  ptr = NULL;//用来记录分隔到那里
    char* s = strtok_r(buff," ",&ptr);//分隔字符串数组
    if ( s == NULL )
    {
        return NULL;
    }
    printf("请求方法:%s\n",s);

    s = strtok_r(NULL," ",&ptr);
    return s;
}
void* thread_fun(void* arg)
{
    int * p = (int*)arg;
    int c = *p;
    free(p);
    while( 1 )
    {
        char buff[1024] = {0};
        int n = recv(c,buff,1023,0);
        if ( n <= 0 )
        {
            break;
        }

        printf("buff=\n%s\n",buff);


        char* filename = get_filename(buff);
        if ( filename == NULL )
        {
            break;
        }

        char path[256] = {PATH};// "/home/stu/桌面/c2305/day21"
        if ( strcmp(filename,"/") == 0 )
        {
            filename = "/index.html";
        }

        strcat(path,filename);
        printf("path:%s\n",path);

        int fd = open(path,O_RDONLY);
        if ( fd == -1 )
        {
            break;
        }

        int filesize = lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);

        char head[256] = {"HTTP/1.1 200 OK\r\n"};
        strcat(head,"Server: myhttp\r\n");
        sprintf(head+strlen(head),"Content-Length: %d\r\n",filesize);
        strcat(head,"\r\n");
        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);
    pthread_exit(NULL);
}

int main()
{
    int sockfd = socket_init();
    if ( sockfd == -1 )
    {
        exit(1);
    }

    while( 1 )
    {
        int c = accept(sockfd,NULL,NULL);
        if ( c < 0 )
        {
            continue;
        }

        pthread_t id;
        int *p = (int*)malloc(sizeof(int));
        *p = c;
        pthread_create(&id,NULL,thread_fun,(void*)p);
    }
}
int socket_init()
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if ( sockfd == -1)
    {
        return -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));
    if ( res == -1 )
    {
        printf("bind err\n");
        return -1;
    }

    if(listen(sockfd,5) == -1 )
    {
        return -1;
    }

    return sockfd;
}

2.html代码

<html>
        <head>
                <meta charset=utf8>
        <title>主页</title>
        </head>

        <body background = "1.jpeg">
                <center>
                <h1>这是主页
                </center>
        </body>

        </html>
~                                                                                                                     
~                                                                                                                     
~                                                                                                                     
~                                                                                                                     
~                 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

果蛋蛋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值