34 | 自己动手写高性能HTTP服务器(三):TCP字节流处理和HTTP协议实现
该思维导图由 AI 生成,仅供参考
buffer 对象
- 深入了解
- 翻译
- 解释
- 总结
本文详细介绍了如何自己动手编写高性能HTTP服务器,主要包括TCP字节流处理和HTTP协议实现。首先讲解了buffer对象的设计和数据结构,以及make_room函数的实现,用于处理缓冲区的扩容操作。接着详细讲解了套接字接收数据处理和套接字发送数据处理的实现细节,包括如何将套接字接收的数据流缓冲到buffer对象中,并通过额外的缓冲触发扩容操作,以及如何将编码后的数据通过套接字缓冲区发送出去。文章还介绍了HTTP协议的解析和处理过程,包括解析状态行、请求头部和请求体等细节。最后,通过一个完整的HTTP服务器例子展示了如何根据不同的HTTP请求信息进行计算和处理,并给出了两道思考题,引发读者深入思考。 整篇文章通过实例程序和详细的代码解析,展现了作者对于高性能HTTP服务器的深入理解和实践经验,为读者提供了一个全面的技术指南。读者可以通过本文了解如何利用buffer对象处理TCP字节流,并实现HTTP协议相关的功能,从而完成高性能HTTP服务器的编写。文章内容丰富,技术深度适中,适合对网络编程和HTTP协议感兴趣的技术人员阅读学习。
《网络编程实战》,新⼈⾸单¥59
全部留言(28)
- 最新
- 精选
- chs老师不明白缓冲区为什么要这样设计。用两块内存当做缓冲区,一个用于接收数据,另一个用于发送数据。这两种方式的优缺点能说一下吗?
作者回复: 这里你的理解有点问题,确实是两个buffer对象,一个input_buffer用来接收数据,这个input_buffer对象的写入是框架的handle_read函数来完成的,同时应用程序不端的将input_buffer里的数据取走,这样handle_read就可以不断的将接收缓冲区的数据写入input_buffer。 另一个buffer对象是output_buffer,应用程序不断的往这个缓冲区里写入待发送的数据,框架里的handle_write函数不端的将缓冲区的数据送到套接字发送缓冲区中。 缓冲区的设计中,肯定是有一个往缓冲区里写入的,另一个从缓冲区里读取数据,否则就没有缓冲区了,而是临时创建一个个的字节流对象。 使用缓冲区可以大大减少对内存的消耗。
2019-11-1528 - keepgoing老师,在tcp_connection.c文件tcp_connection_new方法创建channel时传入的data是tcp_connection类型,但在channel.c中channel_write_event_enable方法会直接从channel->data中取一个event_loop类型指针出来,阅读了整个tcp框架看起来没有找到直接传入event_loop类型的地方,这里是一个代码bug吗
作者回复: 你读的很仔细,我看了一下,确实是有问题的。 最简单的方法是在channel里面保持一个event_loop对象指针,在构建channel时传过来,在channel.c的channel_write_event_enable方法里直接使用这个对象就可以了。 如果可以,欢迎你提一个patch过来,感谢~
2020-09-073 - 罗兆峰第二题: 用户申请图片的时候可以申请一个GET 方法的request, GET URI version, URI 是图片相对服务器程序的地址,在服务器端程序使用io 函数read/或者mmap 读取图片文件的内容, 并且写到connectedfd 中即可, http response 中的文件类型标记为image/png。
作者回复: 赞
2022-02-182 - T------T老师好,发现一个memmem函数运行错误的Bug. 环境:Ubuntu18.04 GCC 10.3 glic 2.33 问题:返回void* 的memmem函数未声明,系统默认调用了返回int的memmem函数。返回值由int强转成char*,导致后续处理出现错误。 解决办法:在#include<string.h> 之前添加#define _GNU_SOURCE解决 参考:https://insidelinuxdev.net/article/a09522.html
作者回复: 嗯,严格来说,所有和OS环境有关联的函数调用,都需要抽象屏蔽一下。
2021-12-0821 - 小家伙54老师,ubuntu20.4运行lib程序会出现段错误,这是怎么回事啊? nuc@nuc-NUC8i5BEHS:~/learn/GeekTime/net_prog/yolanda/build/bin$ ./http_server01 [msg] set epoll as dispatcher, main thread [msg] add channel fd == 5, main thread [msg] set epoll as dispatcher, Thread-1 [msg] add channel fd == 9, Thread-1 [msg] event loop thread init and signal, Thread-1 [msg] event loop run, Thread-1 [msg] event loop thread started, Thread-1 [msg] set epoll as dispatcher, Thread-2 [msg] add channel fd == 12, Thread-2 [msg] event loop thread init and signal, Thread-2 [msg] event loop run, Thread-2 [msg] event loop thread started, Thread-2 [msg] add channel fd == 6, main thread [msg] event loop run, main thread [msg] epoll_wait wakeup, main thread [msg] get message channel fd==6 for read, main thread [msg] activate channel fd == 6, revents=2, main thread [msg] new connection established, socket == 13 [msg] connection completed [msg] epoll_wait wakeup, Thread-1 [msg] get message channel fd==9 for read, Thread-1 [msg] activate channel fd == 9, revents=2, Thread-1 [msg] wakeup, Thread-1 [msg] add channel fd == 13, Thread-1 [msg] epoll_wait wakeup, Thread-1 [msg] get message channel fd==13 for read, Thread-1 [msg] activate channel fd == 13, revents=2, Thread-1 [msg] get message from tcp connection connection-13 段错误 (核心已转储)
作者回复: 貌似是内存访问出错了,你可以看下dump文件,另外,我不能确定是和ubuntu20.4有关。
2021-07-0941 - JeQer没有经过压力测试的服务器怎么能称为高性能呢?
作者回复: 欢迎压测
2021-02-171 - TinyCalf//初始化一个request对象 struct http_request *http_request_new() { struct http_request *httpRequest = malloc(sizeof(struct http_request)); httpRequest->method = NULL; httpRequest->current_state = REQUEST_STATUS; httpRequest->version = NULL; httpRequest->url = NULL; httpRequest->request_headers = malloc(sizeof(struct http_request) * INIT_REQUEST_HEADER_SIZE); httpRequest->request_headers_number = 0; return httpRequest; } 这里的 httpRequest->request_headers = malloc(sizeof(struct http_request) * INIT_REQUEST_HEADER_SIZE); 是不是写错了 ;)
作者回复: 没有哦,这个其实是一个request_header的数组,直接用指针来表示了,这个数组的最大长度是INIT_REQUEST_HEADER_SIZE。因为http request header就是一个数组。
2020-11-171 - J.M.Liuc语言写bbs网站的年代,真的是太疯狂了,一个一个字符的print(哭脸)
作者回复: 是有点疯狂。(哭脸)
2019-11-031 - 沉淀的梦想在ubuntu系统上一运行老师的程序就会出现“interrupted by signal 11: SIGSEGV”错误
作者回复: 我也是ubuntu系统啊,有同学碰到同样的问题么?
2019-10-3061 - dll好不容易看完了 打卡纪念一下
编辑回复: 真棒!
2022-08-04