web服务器学习---HTTP协议总结

对于之前学过的无论是聊天室服务器,还是回射服务器都是在Linux环境下,写一个终端客户端,用户通过客户端和服务器通过定长的数据包或者Json键值包进行交互.而对于web服务器,服务器还是在终端运行,但是客户端成为了浏览器,用户或者爬虫程序通过浏览器和服务器交互数据,对于一些数据格式分析上,C/S两端也应该达成共识,HTTP是一个客户端和服务器端请求和应答的标准.

HTTP协议
在讲述之前,我们先来使用浏览器访问一下百度,然后再按下F12键,再出现的分屏页面找"网络",点击,就会出现另一个分,找消息头,在状态码这一行点击原始头,出现以下信息,这就是本篇文章将要分析的内容:

在这里插入图片描述

在TCP中,服务器启动后,通过在浏览器输入服务器的 IP:端口 来建立连接,建立连接后,浏览器会发送一个请求头,拿以上请求为例,我们请求的IP是www.baidu.com端口属于知名端口,请求的资源紧跟其后为/,百度服务器处理这种请求的结果就是发送一个html网页.

请求方法是GET, 请求指定的页面信息,并返回实体主体。除此之外还有比较常用的POST, 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。

这里有一个html例子可以参考:

<html>
    <head>
        <title></title>
    </head>
    <body>
        <form method="post">
        <div>NAME:<input type="text" value="JAMES" name="user"/></div>
    <br/>
    <div>PASSWORD:<input type="password" value="James" name="pwd"/></div>
    <br/>   
    <div>
        SEX:<select name="sex">
            <option>male<option>
            <option>famale<option>
            </select>
        </div>
        <br/>
        <div>
            <input type="submit" value="SUBMIT"/>
            <input type="button" value="RESET TABLE"/>
        </div>
        </form>
    </body>
</html>

这是一个简单的提交数据信息的html.
提交的效果:
使用post方法:

在这里插入图片描述

使用get方法:
在这里插入图片描述很明显,使用get方法会使我们的提交数据显示在url框中,而使用post方法,它把我们的提交数据都隐藏在了请求行的最后面进行加密处理,不会显示出来,比较安全.

远程地址:即web服务器的地址和端口.

状态码是服务器返回的,200表示数据请求正常,404表示请求的资源不存在.其他的状态码可以参考状态码大全.

版本:即就是HTTP协议的版本号.

请求头

作简单分析吧!

Host:域名

User-Agent:用户代理,因为我们用的就是ubuntu Firefox浏览器来访问Host 的.

Accept:告诉WEB服务器自己接受什么介质类型,/ 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type。

Connection:使用的连接方式,长连接/短连接.此处为长连接.

响应头

挑主要的说吧!

第一行是版本和状态码.

content-type text/html; charset=utf-8 返回数据的格式及字符集编码.

Content-Length 这一次发送的数据长度.

以上是服务器响应浏览器必备的要素,其他的请参考这篇文章

一般浏览器给服务器传过来请求的格式如下:

请求行数据
GET /1.html HTTP/1.1\r\n
Host: 127.0.0.1:2345\r\n
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2\r\n
Accept-Encoding: gzip, deflate\r\n
Connection: keep-alive\r\n
Upgrade-Insecure-Requests: 1\r\n
\n
如果是post请求的话,此处应该有数据.

对于我们作服务器的来说,只关心想要请求的数据是什么?然后发送正确的响应即可.服务器端解析第一行,解析出是get请求,就不用解析最后面的信息了,要是post的话,就得解析最后面的信息.

然后空一空格,取出要请求的资源信息,此处为资源目录下的1.html文件.

在空一格,为HTTP协议版本号.

下面是服务器解析请求头行的实现代码:

//sock 是浏览器套接字 line指向每一行的首地址 s是sizeof(line)
int  get_line( int& sock , char* line ,int& len)
{

    int i = 0 ;
    char c = '\0' ;
    int n  ;

    while( (i < len - 1)&&(c != '\n'))
    {

        n = recv(sock , &c , 1 , 0 ) ;
        if( n == 0 )
        {
            break ;
        }

            if( n > 0 )
            {
                if( c == '\r' )
                {
                    n = recv( sock , &c , 1 , MSG_PEEK ) ;
                    if( n > 0 && c == '\n')
                    {
                        recv(sock , &c , 1 , 0);
                    }
                    else
                    {
                        c = '\n' ;
                    }
                }
                line[i] = c ;
                i++ ;
            }
            else
            {
                c = '\n'  ;  
            }
    }

    line[i] = '\0' ;
    if( n == -1 )
    {
        i = -1 ;
    }
    return i ;  
}

将请求解析出来以后,我们的服务器必须要组建基本的响应头,并发送资源

下面是发送响应的函数代码实现:

//connfd 套接字 no和desc是状态码 type是资源在浏览器中的显示格式以及字符集编码  len发送数据的总长度
send_response_head(int connfd, int no ,const char*desc ,const char *type ,long len){
    
    char buf[1024];

    //状态行
    
    sprintf(buf,"http/1.1 %d %s\r\n",no,desc);
    cout<<buf<<endl;
    send(connfd ,buf ,strlen(buf),0);
    //消息包头
    sprintf(buf,"Content-Type: %s\r\n",type);
    send(connfd ,buf ,strlen(buf),0);
    sprintf(buf+strlen(buf),"Content-Length: %ld\r\n",len);
    send(connfd ,buf ,strlen(buf),0);
    cout<<buf<<endl;
    
    //空行
    sprintf(buf,"\r\n");
    send(connfd ,buf ,2,0);    
}

服务器每次在发送资源之前必须发送响应信息,才能发送资源信息.

下面是基于线程池的web简单的服务器实现:
在这里插入图片描述
git源代码 Welcome Fork And Star

下面是服务器的一些问题,加载页面时,有时候加载不出图片,不知道为什么,看好像是浏览器对图片的请求到不了服务器不知道为什么,很恼火??? 在post请求提交信息时,CGI程序能收到从服务器传来的信息,并通过将客户端套接字指定为标准输出后,请求能不断刷新尝试的情况下(不知为什么出现这些奇怪的buger~~~),请求能到达浏览器的如下图:
在这里插入图片描述

在这里插入图片描述但是在页面上返回的信息只是一闪而过就变成连接已重置,不知道怎么回事???调了一天多,实在不行了!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值