cs144建议我们使用Modern C++来完成所有的lab,关于modern c++的全面的用法可以在(http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)获取。
创新互联专注于企业全网营销推广、网站重做改版、东台网站定制设计、自适应品牌网站建设、html5、商城建设、集团公司官网建设、外贸网站制作、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为东台等各大城市提供网站开发制作服务。以下是一些代码规范:
malloc()
和free()
new
和delete
(FILE)*x
,必要时使用C++的static_cast
char *s
,和C语言中的字符串函数strlen(), strcpy()
,应使用c++中std::string
const Address & address
)make format
来修改代码风格在本次热身实验中,我们将会利用操作系统预先存在的接口来实现一个简单的TCP socket,并利用这个tcp socket来实现对网页的请求。
使用OS的流套接字写一个网络程序这个部分比较简单,只需要按照handout所说,看完TCPSocket,FileDescriptor,Socket和Address这几个类的介绍,就能很快的完成这个程序,其实只需要看TCPSocket
class就行。这些源代码都在libsponge\util
中。
在linux系统中,一切皆文件。
webget.c
void get_URL(const string &host, const string &path) {TCPSocket tsk;
tsk.connect(Address(host,"http"));
tsk.write("GET " + path + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
string str;
while(!tsk.eof()) {tsk.read(str);
cout<< str;
}
tsk.close();
}
注意的是write的字符串要写成HTTP请求的格式,这也就是我们的应用层数据,在通过socket后会封装上TCP头部再丢进网络层传输。
内存中的可靠数据流我们要完成的任务是实现一个类似于管道的数据结构ByteStream,这个channel有两端,一端是input side,负责向channel中输入字符串,另一端是output side,负责从channel中读取字符串并且取出来,在抽象的数据结构中来看,std::deque
双端队列最合适不过。
这个管道是有容量限制的,其在初始化时就会规定好其capacity,作为在任意时刻channel内的大字符量。随着output side对channel内字符串的读取,input side被允许写入更多的字符串,这意味着ByteStream可以传输比其自身capacity更大的数据,换句话就是ByteStream的容量理论上可以达到无限,只要input side持续地write。
在对ByteStream的功能熟悉后,我们就可以在libsponge\byte_stream.hh
和libsonge\byte_stream.cc
的骨架代码中完成我们的实现。这里需要特别强调一下**EOF
的状态:**end of file
是指在input side终止了输入的前提下,output side从channel中读取完了所有的字符串,此时ByteStream中的数据为空,并且不会再有数据输入。
对于ByteStream类,我添加的私有成员如下:
class ByteStream {private:
// Your code here -- add private members as necessary.
size_t _capacity;
bool _eof = false;
std::deque_buffer;
size_t _total_write;
size_t _total_read;
bool _error{}; //!< Flag indicating that the stream suffered an error.
...
}
ByteStream类的方法的实现:
ByteStream::ByteStream(const size_t capa) : _capacity(capa), _eof(false), _buffer(), _total_write(0), _total_read(0) {}
size_t ByteStream::write(const string &data) {size_t remain_size = _capacity - _buffer.size();
size_t len = min(remain_size, data.length());
for (size_t i = 0; i< len; i++)
_buffer.push_back(data[i]);
_total_write += len;
return len;
}
//! \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 l = min(len, _buffer.size());
string output = "";
for (size_t i = 0; i< l; i++)
output += _buffer[i];
return output;
}
//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {size_t l = min(len, _buffer.size());
_total_read += l;
while (l--)
_buffer.pop_front();
}
//! 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 str = peek_output(len);
pop_output(len);
return str;
}
void ByteStream::end_input() {_eof = true; }
bool ByteStream::input_ended() const {return _eof; }
size_t ByteStream::buffer_size() const {return _buffer.size(); }
bool ByteStream::buffer_empty() const {return _buffer.empty(); }
bool ByteStream::eof() const {return _eof && _buffer.empty(); }
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 _capacity - _buffer.size(); }
通过下列指令完成编译;
mkdir build
cd build
cmake ..
make
make check_lab0
结果如下:
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧