一个基于C++11/14的webServer服务器

cppWebServer

一个基于C++11/14的webServer服务器
代码:github
前端代码:目前没有放在github,因为视频太大了,不能上传100m的文件

功能

  • 利用IO复用技术Epoll与线程池实现多线程的Reactor高并发模型;
  • 利用正则与状态机解析HTTP请求报文,实现处理静态资源的请求;
  • 利用标准库容器封装char,实现自动增缩的缓冲区;
  • 基于小根堆实现的定时器,关闭超时的非活动连接;
  • 使用gzip实现大文件的压缩传输,自动识别文件是否压缩,并对带参 URL 进行简单的解析;
  • 利用 RAII 机制实现了数据库连接池,减少数据库连接建立与关闭的开销,同时实现了用户注册登录功能;使用 MySQL,存储用户账号信息;
  • 实现文件的分块传输,断点续传。

编译

  • 发行模式
g++ test.cpp  ./pool/threadPool.cpp   ./http/httpconn.cpp  ./server/webServer.cpp   ./buffer/buffer.cpp  ./server/epoller.cpp ./timer/heaptimer.cpp  ./http/httpRequest.cpp ./http/httpResponse.cpp   -o a.out -lpthread -lz
  • DEBUG模式
g++ test.cpp  ./pool/threadPool.cpp   ./http/httpconn.cpp  ./server/webServer.cpp   ./buffer/buffer.cpp  ./server/epoller.cpp ./timer/heaptimer.cpp  ./http/httpRequest.cpp ./http/httpResponse.cpp   -o a.out -lpthread -lz -D DEBUG

日志

  • 使用了std::unordered_map,不能使用#pragma pack(1),就是不能内存对齐1字节,不能unordered_map在构造的时候会发生段错误。
  • 发现定时器bug,不能对father使用size_t类型,如果child=0时,father会发生类型转变,最后等于一个极大值9223372036854775807
void axy::HeapTimer::siftup_(int child) { //节点上升
    assert(child >= 0 && child < (int)heap_.size());
    // size_t j = (child - 1) / 2;   //child == 0时,j = 9223372036854775807
    int father = (child - 1) >> 1;
    TimerNode temp = heap_[child];
    while(father >= 0) {
        if(heap_[father] < heap_[child]) { break; }
        // _swapNode(child, father);
        heap_[child] = heap_[father];
        child = father;
        father = (child - 1) >> 1;
    }
    heap_[child] = temp;
}

学到

zlib的使用

  • zlib学习小结
  • flush:如果文件过大时,数据不能一次读取进缓冲区进行压缩,那么flush就为Z_NO_FLUSH,告诉gzip这不是最后一次压缩。如果是最后一次压缩,那么flush为Z_FINISH
  • 注意:
    • Z_FINISH对应的正常的返回值为:Z_STREAM_END
    • Z_NO_FLUSH对应的正常的返回值为:Z_OK

需要注意的是

  • zs.avail_out:表示的是用来存储已经被压缩好的数据的缓冲区还有多少个字节的区域没有被使用
    所以,压缩好的数据的大小为 max_buff_size - zs.avail_out
  • 如果zs.avail_out为0,那么表示需要压缩的数据没有完全被压缩,需要继续进行压缩,直到zs.avail_out不为0

一个使用例子

        //压缩
        zs.next_in = (Bytef *)((uint8_t *)_iov[1].iov_base + i * PIECE_ZIP_COND_SIZE/**/);
        zs.avail_in = block_size;
        int flush = (i != block_count - 1) ? Z_NO_FLUSH : Z_FINISH;

        do {
            zs.next_out = (Bytef *)_piece->getBegin();
            zs.avail_out = write_size;

            int rc = deflate(&zs, flush);

            if ((i != block_count - 1) && rc != Z_OK) {
                deflateEnd(&zs);
#ifdef DEBUG
                LOG_WARN("hh\n");
#endif // DEBUG
                return 0; //发送失败
            }

            if ((i == block_count - 1) && rc != Z_STREAM_END) {
                deflateEnd(&zs);
#ifdef DEBUG
                LOG_WARN("gg\n");
#endif // DEBUG
                return 0; //发送失败
            }
            // _iov[1].iov_base = (long *)_iov[1].iov_base + block_size;
            int compressed_size = write_size - zs.avail_out; //压缩后的字节数


        } while (zs.avail_out == 0);

效果

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
断点续传、范围传输效果
在这里插入图片描述

(https://www.youtube.com/watch?v=JZ4Gkx71VIg" “Unity Snake Game”)

Watch the video

前端参考

致谢

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值