剖析tinyhttp源码

来源:互联网 发布:产品样本设计软件 编辑:程序博客网 时间:2024/06/08 18:37

HTTP协议:

1.支持客户端/服务器模式(C/S)(所有客户端都通过访问服务器来获取所需的资源)

C/S模型:服务器启动后,首先创建一个(或者)多个接听套接字(socket),并调用函数bind函数将其绑定到服务器感兴趣的端口上,然后调用listen函数等待客户端的连接。服务器稳定运行后,客户端就可以调用connect函数向服务器发起连接了。客户端连接请求是随机到达的异步事件,服务器使用某种IO技术来接听这一事件,当接听到连接请求后,服务器就调用Accept函数接受他,并分配一个逻辑单元为新的连接服务。新的连接单元可以是新创建的子进程或者其他,逻辑单元读取客户端的请求,并且处理该请求;

C/S模型适用在资源相对集中的场合;

2.简单快速:客户端向服务器请求服务的时,只需要向服务器传送的请求方法和路径。请求请求方法有:GET、POST(客户端向服务器提交数据的方法)、DELETE(删除某个资源)、TRACE(要求目标服务器返回原始HTTP请求的内容,他可以查看中间服务器对HTTP请求的影响)、OPTION(可以知道服务器对某个特定的URL支持那些请求方法);每一种方法对应一种客户端与服务器的连接类型;

3.灵活:HTTP允许传输任意类型的数据对象。正在传输的数据类型由Consistent-Type加以标记;

4.无连接:限制每次连接只能处理一个请求;服务器处理客户的请求,收到客户客户的应答后,断开连接;

5:无状态:HTTP协议是无状态协议,无状态是指他对事物的处理没有记忆功能,缺少状态意味着如果后序处理需要前面所需的信息的话,它必须重新传,这样可能导致,每次传输的数据量增大,另一面当服务其不需要前面信息的时候他的应答很快;

GET:申请获取资源,而不对服务器进行修改;

HEAD:仅要求服务器返回头部信息,而不需要传输任何实际的内容;

TRACE:要求目标服务器返回原始HTTP请求的内容;

POST:客户端向服务器提交数据的方法,这种方法会影响服务器;

PUT:上传某个资源;

DELETE:删除某个资源;

OPTIONS:查看服务器对某个特定的URL都支持哪些方法;

CONNECT:用在代理服务器它能够把请求转化为一个安全隧道;

HTTP请求:

GET http://www.baudu.com/index.html HTTP/1.0

User-Agrent: wget/1.12 (linux-gnu)

Host: www.baidu.com

Connection: close

第一行是请求行 GET表示请求的方法; http是值是指获取目标资源使用的应用层协议 www.baidu.com/index.html是指目标资源的URL;

第2~4行:HTTP请求的头部字段,HTTP可以有很多的头部字段,一个头部字段占一行 User-Argent 表示客户端使用的程序是,Hos指目标主机是www.baidu.com.Connection: close是告诉服务器处理完这个HTTP请求之后关闭连接,WEB客户端和WEB服务器之间的TCP的连接只能为一个HTTP请求服务,同一个客户端的多个连接的HTTP的请求不能共用同一个TCP连接这叫做短连接。与他相反的是长连接;同一个客户端多次请求HTTP服务的时候用同一个tcp连接。Connection 就是来告诉对方处理完一个http服务以后如何处理连接的。

在所有头部字段之后HTTP请求必须包含一个空行,目的是标识一个头部字段的结束;请求行和每个头部字段都必须以<CR><LF>(回车符和换行符)

HTTP应答:

100Continue,服务器收到了客户端的请求行和头部信息,告诉客户端继续发送数据过来;

200 OK 请求成功

301 资源被转移了,请求重新定向;

302 通知客户端资源能够在其他地方能找到,但是需要使用GET方法来获取;


307通知客户端资源可以再其他地方找到,请求方法也可以不用改变就能访问到目标资源;

400 客户端请求失败;

401请求需要认真信息;

40没有访问权限;

404资源没有被找到;

407客户端需要得到代理服务器的认证;

500通用服务器错误;

503暂时无法访问服务器

IP协议:IP的目的是将在复杂环境中的数据包最终发给目标

特点:他为上层协议提供无状态。无连接,不可靠的服务;

无状态:缺点:IP通信的双方不同步数据的状态信息,IP数据报的发送,传输,和接收都是相互独立的;他无法处理重复,乱序的数据报;优点:简单高效;因为不需要为了保存状态信而消耗内核资源,也不需要每次重新传的时候都携带状态信息;

无连接:IP通信的双方都的保持对方的任何信息比较短,那么上层协议每次发数据的时候都必须携带对方的地址;

不可靠:IP协议不能保证数据能够准确的到达对端地址,只是尽最大努力;发送端收到数据发送失败以后通知上层协议发送失败而不会重传;IP服务的上层协议需要自己实现数据的确认,超时重传等机制;

IP分片的重组:IP头部中有数据报标识,标志(DF(禁止分片,MF(更多分片))),片偏移

关于环境变量的几组函数:

int setenv(const char *name, const char *value, int overwrite);

The  setenv()  function  adds the variable name to the environment with
       the value value, if name does not already exist.  If name does exist in
       the  environment,  then  its  value is changed to value if overwrite is
       nonzero; if overwrite is zero, then the value of name is  not  changed.
       This  function makes copies of the strings pointed to by name and value
       (by contrast with putenv(3)).

注意:value则是变量的内容,参数overwrite用来决定是否要改变已经存在的环境变量。如果overwrite不为0,那么该参数会被改变成现在的value,如果overwrite=0,且该环境变量已经有内容,那么这个参数就会被忽略,如果该环境变量没有值,那么当前的环境变量也会被设置为当前的值;

char *getenv(const char *name);//得到环境变量的值;

 int unsetenv(const char *name);将环境变量的值设置为0;

 int putenv(char *string);string必须是name=value这样的一对;

putenv 函数会将参数 string 直接填写到环境表中,不会再为 "name=value" 这个字符串再去分配内存。如果是在一个函数中定义的string,那么在调用该函数后,string 指向的内容可能会被释放,就找不到name环境变量的值了。

#include<stdlib.h>#include<iostream>using namespace std;int main(){    //char *name;    int ret =setenv("name","I am what i will get",1);    if(!ret)    {        cout<<"success"<<endl;    }    else        cout<<"falied setenv"<<endl;    char *val = getenv("name");    if(val ==NULL)    {        cout<<"error getenv"<<endl;    }    cout<<"value"<<val<<endl;     ret =setenv("e","reset:e",1);    if(!ret)    {        cout<<"success"<<endl;    }    else        cout<<"falied setenv"<<endl;    val = getenv("e");    cout<<val<<endl;     /*ret =unsetenv("name");    if(!ret)    {        cout<<"success unset"<<endl;    }    else        cout<<"falied setenv"<<endl;    val = getenv("name");    cout<<val<<endl;*/    string str="putenv";     ret =putenv("me=new");     if(!ret)     {         cout<<"putenv success"<<endl;     }     else         cout<<"putenv failed"<<endl;     char *arry = getenv("me");     if(arry == NULL)     {       cout<< "getenv :putenv failed"<<endl;     }     else     {      cout<<arry<<endl;     }    return 0;}


原创粉丝点击