cs144:lab0


代码见github:cs144_lab

lab0

  • Modern C++: mostly safe but still fast and low-leve:给出了一些建议与规范。
  • 要理解: a Socket is a type of FileDescriptor, and a TCPSocket is a type of Socket

webget

util的类图

实现

void get_URL( const string& host, const string& path )
{
  TCPSocket sock;
  sock.connect(Address(host, "http"));
  string data_send = "GET " + path + " HTTP/1.1\r\nHost: " + host + "\r\n" + "Connection: close\r\n\r\n";
  sock.write(data_send);

  while (!sock.eof()) {
    std::string data_recv;
    sock.read(data_recv);
    std::cout << data_recv;
  }
  sock.close();
}

问题

  • 如果加上std::cout << std::endl;会测试通不过

改进

an in-memory reliable byte stream

实现

这里使用deque,本来使用了queue,但是不能使用迭代器,就不能peek

还有人使用string加双指针来实现

两个文件:

byte_stream.hh

#pragma once

#include <queue>
#include <stdexcept>
#include <string>
#include <string_view>

class Reader;
class Writer;

class ByteStream
{
protected:
  uint64_t _capacity;
  std::deque<char> _queue;
  uint64_t _writen_size;
  uint64_t _read_size;
  bool _end_input;
  bool _error;


  // Please add any additional state to the ByteStream here, and not to the Writer and Reader interfaces.

public:
  explicit ByteStream( uint64_t capacity );

  // Helper functions (provided) to access the ByteStream's Reader and Writer interfaces
  Reader& reader();
  const Reader& reader() const;
  Writer& writer();
  const Writer& writer() const;
};

class Writer : public ByteStream
{
public:
  void push( std::string data ); // Push data to stream, but only as much as available capacity allows.

  void close();     // Signal that the stream has reached its ending. Nothing more will be written.
  void set_error(); // Signal that the stream suffered an error.

  bool is_closed() const;              // Has the stream been closed?
  uint64_t available_capacity() const; // How many bytes can be pushed to the stream right now?
  uint64_t bytes_pushed() const;       // Total number of bytes cumulatively pushed to the stream
};

class Reader : public ByteStream
{
public:
  std::string peek() const; // Peek at the next bytes in the buffer
  void pop( uint64_t len );      // Remove `len` bytes from the buffer

  bool is_finished() const; // Is the stream finished (closed and fully popped)?
  bool has_error() const;   // Has the stream had an error?

  uint64_t bytes_buffered() const; // Number of bytes currently buffered (pushed and not popped)
  uint64_t bytes_popped() const;   // Total number of bytes cumulatively popped from stream
};

/*
 * read: A (provided) helper function thats peeks and pops up to `len` bytes
 * from a ByteStream Reader into a string;
 */
void read( Reader& reader, uint64_t len, std::string& out );

byte_stream.cc

#include <stdexcept>
#include "byte_stream.hh"

using namespace std;

ByteStream::ByteStream( uint64_t capacity ) : _capacity( capacity ),_queue(),_writen_size(0),_read_size(0),_end_input(false),_error(false) {}

void Writer::push( string data )
{
  if(_end_input) return;
  uint64_t push_size = min(data.size(), available_capacity());  //这里截断输入
  
  for(uint64_t i = 0; i < push_size; i++)
  {
    _queue.push_back(data[i]);
  }
  _writen_size += push_size;

}

void Writer::close(){ _end_input = true;}
void Writer::set_error(){_error = true;}
bool Writer::is_closed() const {return _end_input;}

uint64_t Writer::available_capacity() const 
{
  uint64_t a_c = _capacity - _queue.size();
  return a_c;
}

uint64_t Writer::bytes_pushed() const{return _writen_size;}

string Reader::peek() const{return string(_queue.begin(),_queue.end());  //支持迭代器}
bool Reader::is_finished() const{return (_end_input && (_queue.size() == 0));}
bool Reader::has_error() const{return _error;}

void Reader::pop( uint64_t len )
{
  uint64_t pop_size = min(len, _queue.size());
  _read_size += pop_size;
  while(pop_size--)
  {
    _queue.pop_front();
  }  
}

uint64_t Reader::bytes_buffered() const{return _queue.size();}
uint64_t Reader::bytes_popped() const{return _read_size;}

运行结果:
在这里插入图片描述

问题

  • 速度测试失败了,不知道是不是我用的虚拟机的性能问题,换个机器试一试。
  • 在本来提供的代码框架里使用了string_view的特性,但是我的不正确使用导致栈溢出
	std::string_view peek() const; // Peek at the next bytes in the buffer

在这里插入图片描述 为了方便我使用了string替代:

std::string peek() const; // Peek at the next bytes in the buffer

改进

  • 使用string_view
  • 提速

调试

主要是在vscode调试tests中测试代码。配置launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "test debug",
            "type": "cppdbg",
            "request": "launch",    //launch和attach区别
            "program": "${workspaceFolder}/build/tests/${fileBasenameNoExtension}", //调试程序的目录
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",   //json所在文件夹的位置
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        }


    ]
}

选中源文件,这样就能在debug插件一键启动调试二进制文件了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值