check0
Program Structure and Design
3.4 geturl
这个实验非常简单,只需要读懂他这里的API就可以做了,其中从socket里面读数据的方式和pipe是完全一致的,都用read来读,write来写。
首先使用
1 | Address address { host, "http" }; |
来创建一个地址
然后用
1 | TCPSocket socket; |
来创建socket,接下来不断读就行了:
1 | string response; |
这里我处理了一下如果最开始HTTP的状态码不是200的情况
3.5 byte_stream
这个部分主要就是在内存里面模拟实现一个buffer,这里我采用的是用两个 std::deque
来存,一个存原始的string副本(用来创建string_view,不然直接用传入参数创建会导致栈被回收时,提供的指针未定义)另一个存string_view来做切片。
具体实现其实很简单,只要每次push的时候,更新对应的计数器,保存string副本,然后按照可用大小创建string_view切片就行了,但是实际上由于string_view的特性我被坑惨了,具体下一部分讲。
Implementation Challenges
本次实验我遇到的最抽象的bug就是string_view的构造函数,他有两个原型,第一个是
1 | constexpr basic_string_view( const CharT* s ); |
另一个是
1 | constexpr basic_string_view( const CharT* s, size_type count ); |
在cppreference的string_view界面里面,没有告诉我,第一个构造函数会默认以第一个\0
作为字符串的结束,我以为他的原型是
1 | constexpr basic_string_view( const string& str ); |
导致一旦传入的流里面包括了 \0
就会出错,而前面的测试用例太弱了,导致前几个可以模拟的没有出这个错,后面随机几百次的时候才遇到。
解决方案——防御性编程
后续我是使用断言和异常来调试出这个问题的,即添加了判断
1 | if ( data.size() != base_view.size() ) { |
最终让我看出来到底问题在哪里了
Experimental results and performance.
2.1拉取网页
这里使用给出的命令可以拉取对应的网页,但是由于示例里面的 http://cs144.keithw.org/hello 老是408 超时,所以我选择拉取我的博客的主页,下面是截图
补后续:
后面又拉取成功了
2.1发邮件
遇到的第一个问题是,在本地用命令
1 | base64 file |
进行base64编码的时候,输出不知道为什么少了一个=导致根本登不上去
2.2监听网络
利用这个可以发现,在任意一边按回车另一边都会对应显示
3.4 geturl
3.5 byte_stream
这里的速度达到了