Linux 精通 4.2

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”

  1. 多次声明 struct conn:如果 struct conn 在多个文件中被重复声明,而每个声明略有不同,编译器会认为这些声明是不同的类型。
  2. 未包含正确的头文件:可能是因为没有包含定义 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用状态机

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值