HTTP协议与Web服务器的C语言实现

目录

http协议

 Web服务器的实现

连接建立过程

http请求报头

http的应答状态

代码


http协议

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

使用 HTTP 协议的程序一般默认使用 80 端口。

HTTP协议与Web服务器的C语言实现_第1张图片

 Web服务器的实现

连接建立过程

HTTP协议与Web服务器的C语言实现_第2张图片

短连接:close  一次性

长连接:keep-alive  下一次请求时还可以继续使用。现在大部分web都使用长连接。

http请求报头

HTTP协议与Web服务器的C语言实现_第3张图片

上图就是一个请求报文段的示例,重要的地方进行了标注。

http的应答状态

这里我们只简单的介绍几个,其他有兴趣的可以直接百度

200 OK 请求成功
400 Bad Request 通过客户请求错误
404 Forbidden 资源没有找到
500 通用服务器错误
503 暂时无法访问服务器

代码

注:代码其中使用到的页面文件(.html)需要自己提供,并且和程序在同一位置

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PATH "/home/wjy/桌面/tulun/day1217"


int socket_init();
char * get_filename(char buff[]);
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[512]={0};
        int n=recv(c,buff,511,0);
        if(n<=0)
        {
            close(c);
            continue;
        }
        //获取请求文件名称
        printf("read:\n%s\n",buff);
        char * filename=get_filename(buff);
        if(filename==NULL)
        {
            send(c,"404",3,0);
            close(c);
            continue;
        }

        printf("访问的资源名字:%s\n",filename);
        //打开文件
        char path[128]={PATH};
        if(strcmp(filename,"/")==0)
        {
            strcat(path,"/index.html");
        }
        else
        {
            strcat(path,filename);
        }
        int fd=open(path,O_RDONLY);
        if(fd==-1)
        {
            send(c,"404",3,0);
            close(c);
            continue;
        }

        //应答报文
        int size=lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);

        char head[256]={0};
        strcpy(head,"HTTP/1.0 200 OK\r\n");
        strcat(head,"Sever:httpser\r\n");
        printf(head+strlen(head),"Content_Length:%d\r\n",size);
        strcat(head,"\r\n");

        send(c,head,strlen(head),0);
        printf("head:\n%s\n",head);
        char data[1024]={0};
        int num=0;
        while( (num=read(fd,data,1024))>0)
        {
            send(c,data,num,0);

        }
        close(c);
    }
}
char * get_filename(char buff[])
{
    char * s = strtok(buff,"");
    if (s=NULL)
    {
        return NULL;
    }
    printf("请求方法:%s\n",s);
    s=strtok(NULL,"");

    return s;
}
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)
    {
        return -1;
    }

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

你可能感兴趣的:(Linux,c语言,前端,服务器)