首页 > 其他分享 >CS144-Lab0-networking warmup

CS144-Lab0-networking warmup

时间:2023-01-23 21:56:08浏览次数:54  
标签:networking socket read CS144 write Lab0 end string size

lab 地址 :lab0-doc
代码实现:lab0-code

1. 目标

利用官方支持的 TCPSocket ,实现一个 wget 功能,其次,实现一个可靠的字节流。

2. 实现

2.1 webget

实现上比较简单,主要就是:

  • 创建 socket
  • 连接目标 host,port 为默认的 http 端口
  • write 写入 http header
  • read socket 并打印到终端
// should use TCPClient
void get_URL(const string &host, const string &path) {
	// Your code here.
	// 1. init socket
	TCPSocket socket;
	
	// 2. connect to host
	socket.connect(Address(host, "http"));
	
	// 3. send request path
	socket.write("GET " + path + " HTTP/1.1\r\n");
	socket.write("HOST: " + host + "\r\n");
	socket.write("Connection: close\r\n");
	socket.write("\r\n");
	
	// 4. read response data
	while(!socket.eof())
		cout << socket.read();

// 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.
// Then you'll need to print out everything the server sends back,
// (not just one call to read() -- everything) until you reach
// the "eof" (end of file).
}

2.2 ByteSteam

实现一个可靠的字节流类,支持 写入 & 读出,有固定的 capacity,从功能上来说,ByteStream 与 队列的特性非常相似,先进先出,写入的时候顺序排列在字节流后面,读取的时候从头部开始读取并且 pop 出来。
这里选择使用 vector 作为字节流容器(感觉用 queue 就太简单了其次感觉效率没有 vector 高),初始化时直接 reserve 分配好空间,防止 push_back 时 copy 数据造成额外消耗。
读取和写入的接口如下:

// Write a string of bytes into the stream. Write as many // as will fit, and return the number of bytes written.
size_t write(const std::string &data);
// Returns the number of additional bytes that the stream has space for

std::string read(const size_t len);

写入和读取的思路如下,添加 begin 和 end 两个变量用来维护区间,写入时正常 push_back 字符,读取时只需要移动 end 即可,使用 beginend 的时候再对 capacity 取 mod 即可:

核心代码如下(完整参考 lab0-code

//! 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 read_result;
	int read_size = min(buffer_size(), len);
	for (int i = _end; i < _end + read_size; i++) {
		int real_index = i % _capacity;
		read_result += _data[real_index];
	}
	_total_read += read_size;
	_end += read_size;
	return read_result;
}

size_t ByteStream::write(const string &data) {
	int write_size = min(data.size(), remaining_capacity());
	for (int i = _begin, j = 0; i < _begin + write_size; i++, j++) {
		int real_index = i % _capacity;
		_data[real_index] = data[j];
	}
	_begin += write_size;
	_total_written += write_size;
	return write_size;
}

其次有一点需要注意的是,ByteStreameof 判断条件是需要 不会再有写入(调用了 end_input),且缓存都被读取完毕,才会返回 true

3. 测试

标签:networking,socket,read,CS144,write,Lab0,end,string,size
From: https://www.cnblogs.com/lawliet12/p/17065574.html

相关文章