网络编程(四、服务器http实现)

我们上一篇简单实现了一个反应堆,反应堆的程序只是简单的收发数据,并没有什么业务逻辑,所以今天就在反应堆的基础上,添加一个服务器端的htpp协议实现。

4.1 http介绍

在第一篇客户端http请求的时候就已经介绍了(其实还没写,以后再写),所以这里就简单描述一下。

http协议(hyper text Transfer Protocol,超文本传输协议),是因特网中应用最为广泛的一种网络传输协议。Http是一个基于TCP/IP通信协议来传递数据。

HTTP协议工作于客户端-服务器端架构上,浏览器作为HTTP客户端通过URL向HTTP服务器端即web服务器发送所有请求。

web服务器有:Apache服务器,IIS服务器

HTTP默认端口号为80,也可以改为8080或其他端口。

HTTP三点注意事项:

  • HTTP是无连接:无连接的含义是限制每次连接只处理一个请求。
  • HTTP是媒体独立的:这意味着,只要客户端和服务器知道如何处理数据内容,任何类型的数据都可以通过HTTP发送。
  • Http是无状态:无状态是指协议对于事务处理没有记忆能力。

4.2 服务器响应的消息

http响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

在这里插入图片描述

具体返回的一个请求:
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: “34aa387-d-1568eb00”
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain

注意:
服务器响应消息,最后都要加\r\n\r\n。要不然一直转圈圈

4.3 状态码

在这里插入图片描述
状态码分为5大类,上面的思维导图中,已经分类清楚了,比较常用的是4xx,是客户端出现错误了,5xx是服务器出现了错误,2xx也比较熟悉,200就是接收成功了。

4.4 content-type

在这里插入图片描述
这是从菜鸟教程中截取出来,服务器返回的数据一定要带上content-type,这个字段的意思就是给客户端说明需要以什么方式的格式去解析服务器返回的数据,之前实现的时候,就是忘记了写了这个字段,所以一直报错。

4.5 实现

接下来我们就简易的实现了一个http sever版,在上一节课的reactor之上实现的,reactor属于网络接入层,http属于应用层,reactor把数据准备好之后,往http层发送就可以了。

4.5.1 修改reactor的程序

把之前一个buff的修改成2个buff,并且注册回调函数,在接收数据的回调函数调用这个回到,把整个数据传输到http应用层。

//对 socket疯转
struct nty_event
{
    int fd;
    int events;

    int status;
    void *arg;
    int (*callback)(int fd, int events, void *arg);    //回调函数
    long last_active;

    char sbuffer[1024];
    int slen;

    char rbuf[1024];
    int rlen;
};


struct nty_reactor
{
    int epfd;
    struct nty_event *event;
    HANDLER *handler;
};

回调函数:

void *http_handler(void *arg)
{
    struct nty_event *ev = (struct nty_event *)arg;

    //解析接收到的数据
    char *rbuffer = ev->rbuffer;


    //准备好需要返回的数据
    char *sbuffer = ev->sbuffer;

    


}

4.5.2 客户端数据

简单的接收发送框架已经搭建好,接下来就要尝试接收客户端发来的数据了,我们通过浏览器往我们服务器发送数据,先看我们浏览器抓起的数据:
在这里插入图片描述
通过浏览器的f12我们也能看到客户端发送的请求,另外我在在服务器端把接收的数据打印出来了:
在这里插入图片描述
这样一对比,就是我们刚才发送的数据

4.5.3 解析客户端数据

接下来我们主要解析客户端数据,我们知道http的请求,都是以一行做为单位的,所以我们需要每行都需要读取,

for(; index < rlen; ){
        memset(line, 0, 1024);
        index = read_line(rbuffer, rlen, line, index);
        //printf("line %d %s\n", index, line);
        if(index <= 0) {
           ev->slength = send_erron(sbuffer, 404);
           return ;
        } else if(index < rlen){
            char * ret = strtok(line, " ");
            if(strcmp(ret, "GET") == 0) {
                //需要解析账号密码
                char * soucer = strtok(NULL, " ");
                printf("soucer %s\n", soucer);



                ev->slength = send_erron(sbuffer, 200);
            }
        } 
   }

4.5.4 解析url

http://192.168.0.104:8889/source?name=chen&pwd=123456

解析上面写的带有特殊字符的url,目前没想到比较好的方法,只能想到用切割字符串的方式切割,所以暂时先不用吧,以后分析分析解析http服务器的源码的时候,再回来添加。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值