前言
C++网络库有很多。handy是一个C++11风格的网络库,对深入学习C++有很大帮助。
代码分析
下面是来自handy/raw_examples下的epoll.cc文件。是水平触发的一个示例。该http服务器无论接收到什么样的请求,都返回一个静态资源123456。编译:c++ -o epoll epoll.cc,运行: sudo ./epoll。源代码中sendRes的if (con.writeEnabled)这句似乎有些问题,导致发送超大资源时出现问题。我已经做了修改,使之能够正确发送超大文件。
/*
* 编译:c++ -o epoll epoll.cc
* 运行: ./epoll
* 测试:curl -v localhost
*/
/*
运行效果
使用sudo 运行epoll程序。该程序在本机0.0.0.0的80端口监听,作为一个http服务器运行
每当有连接访问时,返回静态资源httpRes
LT是默认模式
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
运行效果
sudo ./epoll
fd 4 listening at 80
add fd 4 events read 1 write 0
epoll_wait return 1
this is accept
accept a connection from 127.0.0.1
add fd 5 events read 1 write 0
epoll_wait return 1
this can read
read 412 bytes
now info is
---GET / HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Upgrade-Insecure-Requests: 1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,und;q=0.8,zh-TW;q=0.7,en;q=0.6,pl;q=0.5
---
write 4081834 bytes left: 14966851
update it to EPOLLIN|EPOLLOUT
mod fd 5 events read 1 write 4
nothing to read from 5, return.
epoll_wait return 1
handling epollout
write 2226422 bytes left: 12740429
epoll_wait return 1
handling epollout
write 2095456 bytes left: 10644973
epoll_wait return 1
handling epollout
write 1964490 bytes left: 8680483
epoll_wait return 1
handling epollout
write 1506109 bytes left: 7174374
epoll_wait return 1
handling epollout
write 1833524 bytes left: 5340850
epoll_wait return 1
handling epollout
write 1637075 bytes left: 3703775
write 130966 bytes left: 3572809
epoll_wait return 1
handling epollout
write 1571592 bytes left: 2001217
epoll_wait return 1
handling epollout
write 1440626 bytes left: 560591
epoll_wait return 1
handling epollout
write 560591 bytes left: 0
mod fd 5 events read 1 write 0
epoll_wait return 1
this can read
read 375 bytes
now info is
---GET /favicon.ico HTTP/1.1
Host: 127.0.0.1
Connection: keep-alive
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,und;q=0.8,zh-TW;q=0.7,en;q=0.6,pl;q=0.5
---
write 10477280 bytes left: 8571405
update it to EPOLLIN|EPOLLOUT
mod fd 5 events read 1 write 4
nothing to read from 5, return.
epoll_wait return 1
handling epollout
write 1440626 bytes left: 7130779
epoll_wait return 1
handling epollout
write 1768041 bytes left: 5362738
epoll_wait return 1
handling epollout
write 1571592 bytes left: 3791146
epoll_wait return 1
handling epollout
write 1637075 bytes left: 2154071
epoll_wait return 1
handling epollout
write 1702558 bytes left: 451513
epoll_wait return 1
handling epollout
write 451513 bytes left: 0
mod fd 5 events read 1 write 0
epoll_wait return 0
epoll_wait return 0
epoll_wait return 0
这里我发送的资源改大了,改成如下的数值:
httpRes = "HTTP/1.1 200 OK\r\nConnection: Keep-Alive\r\nContent-Type: text/html; charset=UTF-8\r\nContent-Length: 19048576\r\n\r\n123456";
// 将剩下的内容填充成0。最后content的长度是大约1024*1024
for(int i=0;i<19048570;i++) {
httpRes+='\0';
}
可以看到分了多次传输。最终终端页面上显示123456,后面全都是\0,不会显示。
可以看到浏览器请求了两次,一次请求根目录,一次请求页面的图标favicon.ico