Lab0主要是热身。
task1和task2比较简单,按他指示来就行,略。
task3
写一个WebGet,代码如下:
void get_URL(const string &host, const string &path) {
// Your code here.
// You will need to connect to the "http" service on
// the computer whose name is in the "host" string,
// then request the URL path given in the "path" string.
TCPSocket sock;
sock.connect(Address(host, "http"));
string buf = "";
buf += "GET " + path + " HTTP/1.1\r\n";
buf += "Host: " + host + "\r\n";
buf += "Connection: close\r\n\r\n";
sock.write(buf);
while(!sock.eof()) {
cout << sock.read();
}
sock.close();
}
主要每一行最后都是\r\n
,最后一行结束需要再加一个空行\r\n
task4
task4是写一个内存中的可靠字节流。
用std中的deque就能满足需求。
class ByteStream {
private:
// Your code here -- add private members as necessary.
// Hint: This doesn't need to be a sophisticated data structure at
// all, but if any of your tests are taking longer than a second,
// that's a sign that you probably want to keep exploring
// different approaches.
bool _error{}; //!< Flag indicating that the stream suffered an error.
std::deque<char> _buf;
bool _input_ended;
size_t _bytes_written;
size_t _bytes_read;
size_t _capacity;
public:
//! Construct a stream with room for `capacity` bytes.
ByteStream(const size_t capacity);
//! \name "Input" interface for the writer
//!@{
//! Write a string of bytes into the stream. Write as many
//! as will fit, and return how many were written.
//! \returns the number of bytes accepted into the stream
size_t write(const std::string &data);
//! \returns the number of additional bytes that the stream has space for
size_t remaining_capacity() const;
//! Signal that the byte stream has reached its ending
void end_input();
//! Indicate that the stream suffered an error.
void set_error() { _error = true; }
//!@}
//! \name "Output" interface for the reader
//!@{
//! Peek at next "len" bytes of the stream
//! \returns a string
std::string peek_output(const size_t len) const;
//! Remove bytes from the buffer
void pop_output(const size_t len);
//! Read (i.e., copy and then pop) the next "len" bytes of the stream
//! \returns a string
std::string read(const size_t len);
//! \returns `true` if the stream input has ended
bool input_ended() const;
//! \returns `true` if the stream has suffered an error
bool error() const { return _error; }
//! \returns the maximum amount that can currently be read from the stream
size_t buffer_size() const;
//! \returns `true` if the buffer is empty
bool buffer_empty() const;
//! \returns `true` if the output has reached the ending
bool eof() const;
//!@}
//! \name General accounting
//!@{
//! Total number of bytes written
size_t bytes_written() const;
//! Total number of bytes popped
size_t bytes_read() const;
//!@}
};
具体实现
ByteStream::ByteStream(const size_t capacity)
: _buf(0)
, _input_ended(false)
, _bytes_written(0)
, _bytes_read(0)
, _capacity(capacity){}
size_t ByteStream::write(const string &data) {
// DUMMY_CODE(data);
// return {};
// printf("write(%s)\n", data.c_str());
int writen_size = remaining_capacity() < data.length() ? remaining_capacity() : data.length();
for (int i = 0; i < writen_size; i++) {
_buf.push_back(data[i]);
}
_bytes_written += writen_size;
return writen_size;
}
//! \param[in] len bytes will be copied from the output side of the buffer
string ByteStream::peek_output(const size_t len) const {
// peek意味着偷看一眼
// peak才是山峰
// printf("peek(%lu)\n", len);
int length = len < buffer_size() ? len : buffer_size();
// return string(_buf.begin(), _buf.end() + length);
return string().assign(_buf.begin(), _buf.begin() + length);
}
//! \param[in] len bytes will be removed from the output side of the buffer
void ByteStream::pop_output(const size_t len) {
// DUMMY_CODE(len);
// printf("pop(%lu)\n", len);
size_t length = len < buffer_size() ? len : buffer_size();
_bytes_read += length;
while(length--) {
_buf.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) {
// DUMMY_CODE(len);
// return {};
// printf("read(%lu)\n", len);
string ret_str = peek_output(len);
pop_output(len);
return ret_str;
}
void ByteStream::end_input() {
_input_ended = true;
}
bool ByteStream::input_ended() const { return _input_ended; }
size_t ByteStream::buffer_size() const { return _buf.size(); }
bool ByteStream::buffer_empty() const { return _buf.empty(); }
bool ByteStream::eof() const { return input_ended() && buffer_empty(); }
size_t ByteStream::bytes_written() const { return _bytes_written; }
size_t ByteStream::bytes_read() const { return _bytes_read; }
size_t ByteStream::remaining_capacity() const {
return _capacity - _buf.size();
}
结果
满混!