标签:networking string warmup CS144 len length const ByteStream size
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
是否超出了限制就行了。
标签:networking,string,warmup,CS144,len,length,const,ByteStream,size 来源: https://www.cnblogs.com/weijunji/p/cs144-study-1.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。