CS144学习(1)Lab 0: networking warmup

CS144的实验就是要实现一个用户态TCP协议,对于提升C++的水平以及更加深入学习计算机网络还是有很大帮助的。

第一个Lab是环境配置和热身,环境按照文档里的配置就行了,前面两个小实验就是按照步骤来的,就不细讲了。

Writing webget

这一个实验是要用他封装好的socket库写一个简单的http客户端。看看文档里Address和TCPSocket类的介绍就行了。

void get_URL(const string &host, const string &path) { TCPSocket sock; sock.connect(Address(host, "http")); sock.write("GET " + path + " HTTP/1.1\r\n"); sock.write("Host: " + host + "\r\n"); sock.write("Connection: close \r\n"); sock.write("\r\n"); while(!sock.eof()){ auto rsp = sock.read(); cout << rsp; } sock.close(); }

注意就是输出的时候要原封不动地输出内容,也不能任何内容(包括回车),不然会通过不了检查。

An in-memory reliable byte stream

这一个就是要实现一个循环缓冲区ByteStream,并实现一系列的函数实现对其的读写等操作。我这里底层是使用vector来实现。

class ByteStream { private: std::vector<char> buffer; size_t head = 0; size_t tail = 0; size_t length = 0; size_t cap = 0; size_t total_read = 0; size_t total_write = 0; bool end = false; bool _error{}; //!< Flag indicating that the stream suffered an error. ... } ByteStream::ByteStream(const size_t capacity) : buffer(capacity), cap(capacity) {} size_t ByteStream::write(const string &data) { size_t wlen; if(data.length() > cap - length){ wlen = cap - length; }else{ wlen = data.length(); } for(size_t i = 0; i < wlen; i++){ buffer[tail] = data[i]; tail = (tail + 1) % cap; } length += wlen; total_write += wlen; return wlen; } //! \param[in] len bytes will be copied from the output side of the buffer string ByteStream::peek_output(const size_t len) const { size_t rlen; if(len > length){ rlen = length; }else{ rlen = len; } string res(rlen, 0); size_t p = head; for(size_t i = 0; i < rlen; i++){ res[i] = buffer[p]; p = (p + 1) % cap; } return res; } //! \param[in] len bytes will be removed from the output side of the buffer void ByteStream::pop_output(const size_t len) { if(len > length){ length = 0; head = this->tail; total_read += length; }else{ length -= len; head = (head + len) % cap; total_read += len; } } //! Read (i.e., copy and then pop) the next "len" bytes of the stream //! \param[in] len bytes will be popped and returned //! \returns a string std::string ByteStream::read(const size_t len) { string res = peek_output(len); pop_output(len); return res; } void ByteStream::end_input() { end = true; } bool ByteStream::input_ended() const { return end; } size_t ByteStream::buffer_size() const { return length; } bool ByteStream::buffer_empty() const { // cout << len << endl; return length == 0; } bool ByteStream::eof() const { return end && length == 0; } size_t ByteStream::bytes_written() const { return total_write; } size_t ByteStream::bytes_read() const { return total_read; } size_t ByteStream::remaining_capacity() const { return cap - length; }

整个实现还是很简单的,就是记得判断一下输入的len是否超出了限制就行了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwgws.html