reactor应用
response:回应的数据组织成包;request解析对方发来的data
touch webserver.c
int http_request(struct conn *c){
// 传connect信息
printf("request: %s\n", c->rbuffer)
}
int http_response(struct conn *c){
}
改reactor.c 的recv_cb
#if 0 // echo
conn_list[fd].wlength = conn_list[fd].rlength;
memcpy(conn_list[fd].wbuffer, conn_list[fd].rbuffer, conn_list[fd].wlength);
printf("[%d] RECV: %s\n", conn_list[fd].rlength, conn_list[fd].rbuffer);
#else
http_request(&conn_list[fd]);
send_cb
int send_cb(int fd) {
#if 1
http_response(&conn_list[fd]);
#endif
在读完数据request, 在发数据前response
编译一堆报错
touch server.h
#ifndef __SERVER_H__
#define __SERVER_H__
#define BUFFER_LENGTH 1024
typedef int (*RCALLBACK)(int fd);
// reactor里的
struct conn {
int fd;
char rbuffer[BUFFER_LENGTH];
int rlength;
char wbuffer[BUFFER_LENGTH];
int wlength;
RCALLBACK send_callback;
union {
RCALLBACK recv_callback;
RCALLBACK accept_callback;
} r_action;
};
//函数声明
int http_request(struct conn *c);
int http_response(struct conn *c);
#endif
reactor.c里#include “server.h”
- 多次声明
struct conn
:如果struct conn
在多个文件中被重复声明,而每个声明略有不同,编译器会认为这些声明是不同的类型。 - 未包含正确的头文件:可能是因为没有包含定义
struct conn
的头文件,导致编译器认为这是一个不同的类型。
gcc -mcmodel=medium -o webserver reactor.c webserver.c
./webserver
网络助手连正常
断开网络助手浏览器连
加response打印信息, reactor.c recv_cb的epollout反注释回来
int http_response(struct conn *c){
c->wlength = sprintf(c->wbuffer,
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 82\r\n"
"Date: Tue, 30 Apr 2024 13:16:46 GMT\r\n\r\n"
上面都是http 头, 下面是body,都要\r\n结尾
"<html><head><title>0voice.king</title></head><body><h1>King</h1></body></html>\r\n\r\n");
}
网页信息展现了——网页展示的都是string!!!!
梳理
来的io可读recv,还可写send
业务层/协议层
如果response文件
#include <stdio.h>
#include <unistd.h>
#include"server.h"
#include <sys/stat.h>
#include <fcntl.h>
#define WEBSERVER_ROOTDIR "./"
int http_request(struct conn *c){
// 传connect信息
printf("request: %s\n", c->rbuffer);
}
int http_response(struct conn *c){
#if 0
c->wlength = sprintf(c->wbuffer,
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 82\r\n"
"Date: Tue, 30 Apr 2024 13:16:46 GMT\r\n\r\n"
"<html><head><title>0voice.king</title></head><body><h1>King</h1></body></html>\r\n\r\n");
#else
int filefd = open("index.html", O_RDONLY); //读文件
struct stat stat_buf;
fstat(filefd, &stat_buf); //读长度
c->wlength = sprintf(c->wbuffer,
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: %ld\r\n"
"Date: Tue, 30 Apr 2024 13:16:46 GMT\r\n\r\n",
stat_buf.st_size);
int count = read(filefd, c->wbuffer + c->wlength, BUFFER_LENGTH - c->wlength);
c->wlength += count;
close(filefd);
#endif
}
太大了发不完——连续多次发送
梳理一下,
读完查可写? 写完查可读?
server.h用状态机