-
服务器测试环境
- WSL2 + Ubuntu版本16.04
- MySQL版本5.7.33
-
浏览器测试环境
- Windows + Chrome
测试前确认已安装MySQL数据库
# 安装
sudo apt-get update
sudo apt-get install mysql-server
# 启动、关闭、重启 MySQL服务
sudo service mysql start
sudo service mysql stop
sudo service mysql restart
sudo service mysql status #查看状态
# 登录 MySQL服务
mysql -h localhost -P 3306 -u root -p # 远程
mysql -u root -p # 本机
#建立yourdb库
create database yourdb;
#创建user表
USE yourdb;
CREATE TABLE user(
username char(50) NULL,
passwd char(50) NULL
)ENGINE=InnoDB;
#添加数据
INSERT INTO user(username, passwd) VALUES('name', 'passwd');
- 修改main.c中的数据库初始化信息
// 第一个 root 为服务器数据库的登录名,一般为 root
// 第二个 root 为服务器数据库的密码,也就是安装mysql时设置的密码
// yourdb修改为上述创建的yourdb库名
connPool->init("localhost", "root", "root", "yourdb", 3306, 8);
- 修改http_conn.cpp中的root路径
// 修改为root文件夹所在路径
// 也就是将 /home/qgy/ 修改为 TinyWebServer 文件夹所在的目录
const char* doc_root="/home/qgy/TinyWebServer/root";
- 生成server
# 在 /home/qgy/TinyWebServer 目录中执行
make server
- 启动server
# 将 port 修改为具体的端口号,如 ./server 9006
./server port
- 浏览器端
# ip 和 port 均为具体值,如 127.0.0.1:9006
ip:port
项目搭建了一个半同步/半反应堆线程池
,其中维护了一个请求队列
- 线程池中的
主线程
- 通过 epoll 来监听 socket
- 将请求队列中的任务分配给线程池中的工作线程
工作线程
处理的任务分为:- 日志输出
- 定时器处理非活动连接
- 处理http请求
web服务器通过 socket 监听来自用户的请求
- socket:根据指定的地址族、数据类型和协议来分配一个socket的描述字及其所用的资源
int socket(int domain, int type, int protocol);
domain:协议族,常用的有AF_INET、AF_INET6、AF_LOCAL、AF_ROUTE其中AF_INET代表使用ipv4地址
type:socket类型,常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等
protocol:协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、IPPROTO_SCTP、IPPROTO_TIPC等
htonl, htons:
- 网络字节顺序与本地字节顺序之间的转换函数
- htonl(): 针对32位,4字节
- htons(): 针对16位,2字节
- 所占位数小于一个字节,8位时,不需要转换
setsockopt:
- 获取或者设置与某个套接字关联的选项
// s: 套接字描述符
// level: 被设置的选项的级别,如果想要在套接字级别上设置选项,就必须把level设置为 SOL_SOCKET
// optname: SO_REUSEADDR,打开或关闭地址复用功能
// optval: 当 optval 不等于0时,打开,否则,关闭
// optlen: optval 缓冲区的长度
int setsockopt(SOCKET s, int level, int optname, const char FAR *optval, int optlen);
fcntl:
- 修改已经打开文件的属性
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
// 获取、设置文件访问状态标志: F_GETFL、F_SETFL