首页 > 其他分享 >【斯坦福CS144】Lab2

【斯坦福CS144】Lab2

时间:2024-10-08 16:20:48浏览次数:3  
标签:uint64 Wrap32 stream inbound seqno CS144 斯坦福 Lab2 message

一、实验目的

实现一个 TCPReceiver,用以接收传入的 TCP segment 并将其转换成用户可读的数据流。

二、实验内容

1.接收TCP segment;

2.重新组装字节流(包括EOF);

3.确定应该发回给发送者的信号,以进行数据确认和流量控制。

三、实验过程

输入git merge origin/check2-startercode 获取Lab2

用文本编辑器打开./src/wrapping_integers.hh

修改代码,代码分析见注释

用文本编辑器打开./src/wrapping_integers.cc

修改代码,代码分析见注释

在build目录下输入make编译可执行文件

输入make check2测试程序

发现转换测试全部通过,但TCP接收测试失败,需要修改TCP接收的源码。用文本编辑器打开./src/tcp_receiver.hh

修改代码

用文本编辑器打开./src/tcp_receiver.cc

修改代码

重新在build目录下输入make编译可执行文件

再次输入make check2进行测试

发现全部通过

实验结束

四、实验体会

1.本实验中,TCPReceiver 除了将读入的数据写入至 ByteStream 中以外,它还需要告诉发送者两个属性:

第一个未组装的字节索引,称为确认号ackno,它是接收者需要的第一个字节的索引。

第一个未组装的字节索引和第一个不可接受的字节索引之间的距离,称为 窗口长度window size。

ackno 和 window size 共同描述了接收者当前的接收窗口。接收窗口是 发送者允许发送数据的一个范围,通常 TCP 接收方使用接收窗口来进行流量控制,限制发送方发送数据。

2.下图是CS144 对 TCP receiver 的期望执行流程:

三次握手:

3.本部分需要注意结合前一个lab流重组器进行理解,如果字节流未按序到达,那么bytes_written()返回的还是按序到达的最后一个字节的序号。

五、代码附录

wrapping_integers.hh

#pragma once

#include <cstdint>

/*
 * Wrap32 类型表示一个32位无符号整数,具有以下特性:
 *    - 从任意“零点”(初始值)开始。
 *    - 当它达到 2^32 - 1 时会回到零点。
 */

class Wrap32
{
protected:
  uint32_t raw_value_ {}; // 存储32位无符号整数的值

public:
  explicit Wrap32( uint32_t raw_value ) : raw_value_( raw_value ) {} // 构造函数,给定一个无符号32位整数作为参数

  /* 根据绝对序列号 n 和零点构造一个 Wrap32 对象。*/
  static Wrap32 wrap( uint64_t n, Wrap32 zero_point );

  /*
   * unwrap 方法返回一个绝对序列号,它回到这个 Wrap32 对象,给定零点和一个“检查点”:
   * 一个接近期望答案的绝对序列号。
   *
   * 有许多可能的绝对序列号,它们都会回到同一个 Wrap32 对象。
   * unwrap 方法应该返回最接近检查点的那个序列号。
   */
  uint64_t unwrap( Wrap32 zero_point, uint64_t checkpoint ) const;

  // 重载加法运算符,用于增加一个无符号32位整数
  Wrap32 operator+( uint32_t n ) const { return Wrap32 { raw_value_ + n }; }

  // 重载相等运算符,用于比较两个 Wrap32 对象是否相等
  bool operator==( const Wrap32& other ) const { return raw_value_ == other.raw_value_; }

  // 获取原始值
  uint32_t get_raw_value() const {return raw_value_;}
};

wrapping_integers.cc

#include "wrapping_integers.hh"
//#include<algorithm>
using namespace std;

Wrap32 Wrap32::wrap( uint64_t n, Wrap32 zero_point )
{
  // Your code here.
  //(void)n;
  //(void)zero_point;
  //uint32_t raw_value = zero_point + static_cast<uint32_t>n;


  return (zero_point + static_cast<uint32_t>(n));
}

uint64_t Wrap32::unwrap( Wrap32 zero_point, uint64_t checkpoint ) const
{
  // Your code here.
  //(void)zero_point;
  //(void)checkpoint; 
  //uint64_t all_1=0x 0000 0000 FFFF FFFF;
  //uint64_t num = checkpoint/(static<uint64_t>all_1);
  //Wrap32 wrap_checkpoint = wrap(checkpoint, zero_point);
  

  uint64_t num = checkpoint >> 32;
  
  //uint64_t absolute_seqno=0;
  //uint32_t all_1=0xFFFFFFFF;
  uint32_t zero2raw_distance = this->get_raw_value() - zero_point.get_raw_value() ;
  //zero2raw_distance = static_cast<uint64_t> (zero2raw_distance);

  //转换为64之后,在checkpoint附近有三个长度为2^32的段,每个段都有一个点,我把这三个点都检查一遍,看哪个点的距离最近
  uint64_t ans2=(num<<32) + zero2raw_distance;
  uint64_t distance2;
  if(ans2>=checkpoint)distance2 = ans2-checkpoint;
  else distance2 = checkpoint - ans2;

  //这里要判断一下num能不能减一
  uint64_t ans1=((num-1)<<32) + zero2raw_distance;
  if(num==0) ans1=ans2;
  uint64_t distance1 = checkpoint - ans1;

  uint64_t ans3=((num+1)<<32) + zero2raw_distance;
  uint64_t distance3 = ans3 - checkpoint;

  uint64_t mindis ;//= min(distance1, min(distance2, distance3));
  mindis = distance2>distance3? distance3:distance2;
  mindis = mindis>distance1? distance1:mindis;

  if(mindis==distance1)return ans1;
  else if(mindis==distance2)return ans2;
  else  return ans3;
}

tcp_receiver.hh

#pragma once

#include "reassembler.hh"
#include "tcp_receiver_message.hh"
#include "tcp_sender_message.hh"

class TCPReceiver
{

private:
  bool receive_syn{false};
  Wrap32 SYN_seqno{0};
public:
  /*
   * The TCPReceiver receives TCPSenderMessages, inserting their payload into the Reassembler
   * at the correct stream index.
   */
  void receive( TCPSenderMessage message, Reassembler& reassembler, Writer& inbound_stream );

  /* The TCPReceiver sends TCPReceiverMessages back to the TCPSender. */
  TCPReceiverMessage send( const Writer& inbound_stream ) const;
};

tcp_receiver.cc

#include "tcp_receiver.hh"
#include<optional>
using namespace std;

void TCPReceiver::receive( TCPSenderMessage message, Reassembler& reassembler, Writer& inbound_stream )
{
  // Your code here.
  //(void)message;
  //(void)reassembler;
  //(void)inbound_stream;
  if(receive_syn==false&&message.SYN==false)return;//没有syn直接返回
  if(message.SYN)
  {
    SYN_seqno = message.seqno;
    message.seqno = message.seqno + 1;//去掉syn位
    receive_syn=true;
  }
  uint64_t stream_index = message.seqno.unwrap(SYN_seqno, inbound_stream.bytes_pushed()+1) - 1;
  reassembler.insert(stream_index, message.payload.release(), message.FIN, inbound_stream);
  return;
}

TCPReceiverMessage TCPReceiver::send( const Writer& inbound_stream ) const
{
  // Your code here.
  //(void)inbound_stream;
  //uint64_t ack_stream_index = inbound_stream.bytes_pushed() + 1;
  //uint64_t ack_absolute_seqno = ack_stream_index + 1;
  TCPReceiverMessage sendmessage{};
  sendmessage.window_size = inbound_stream.available_capacity()>UINT16_MAX? UINT16_MAX:inbound_stream.available_capacity();
  //if(sendmessage.window_size>=UINT16_MAX) sendmessage.window_size=UINT16_MAX;

  if(receive_syn==false)return sendmessage;
  else
  {
    uint64_t ack_absolute_seqno = inbound_stream.bytes_pushed() + 1 + inbound_stream.is_closed();
    Wrap32 ackno = Wrap32::wrap(ack_absolute_seqno, SYN_seqno);
    sendmessage.ackno.emplace(ackno);
  }

  return sendmessage;
}

标签:uint64,Wrap32,stream,inbound,seqno,CS144,斯坦福,Lab2,message
From: https://blog.csdn.net/qq_37293468/article/details/142762905

相关文章

  • 斯坦福:合成LLM持续预训练语料
    ......
  • Matlab2022a安装教程,Matlab安装包详细安装教程
    Matlab2022a安装教程,Matlab安装包详细安装教程MatlabR2022a安装教程:1、解压缩下载好的文件,打开文件夹2、右击“R2022a_Windows.iso”,选择“装载”,或者直接双击打开3、右击“setup.exe”,选择“以管理员身份运行”4、点击“高级选项”,选择“我有文件安装密钥”5、......
  • 斯坦福大学2014机器学习教程中文笔记目录
    http://www.ai-start.com/ml2014/第一周一、引言(Introduction)1.1欢迎1.2机器学习是什么?1.3监督学习1.4无监督学习二、单变量线性回归(LinearRegressionwithOneVariable)2.1模型表示2.2代价函数2.3代价函数的直观理解I2.4代价函数的直观理解II2.5梯......
  • 探索人工智能的未来:埃里克·施密特2024斯坦福大学分享四
    一、语言模型的经济影响关于语言模型的经济影响,我想先谈谈市场的影响。我们看到一些服务领域的变化速度比预期的要慢,比如CHEG和其他相关服务的表现。对此,您是否认为学术界应该获得人工智能补贴?还是说,他们应该与大公司合作?我个人非常努力地推动为大学争取数据中心。如果......
  • 斯坦福大学深度解析:机器学习优化算法全攻略
    在全球人工智能研究的浪潮中,斯坦福大学以其卓越的学术成就和前沿的研究成果,一直站在该领域的前沿。今天,我们将深入探讨斯坦福大学关于机器学习优化算法的精华讲义,这份讲义不仅包含了丰富的理论知识,还有图解和Pytorch实现代码,是学习和实践机器学习优化算法的宝贵资源。↓↓↓......
  • [CS61A] 学习记录六 Lab2 题解思路分享
    前言观前提示,笔者写的代码答案放在GitHub仓库中,此处仅记录过程与心得。此外,请最好在尝试独立完成该任务后再看本文,否则就很可能失去了体验本项目精华的机会正文Q1:WWPD:LambdatheFree有两个问题有点意思。lambda与参数>>>b=lambdax:lambda:x#Lambdascanr......
  • 卷积神经网络--卷积层(斯坦福李飞飞学习笔记)
    卷积核对于图像分类任务,常见的卷积核(kernel)大小可以是3x3、5x5个像素点注意一下词汇的辨析:kernel是二维的,也就是每一层的卷积核大小;filter表示的是三维的,所以可以看到ppt里面的filter展示的是5*5*3,因为kernel的大小是5*5,同时放入的图像是RGB类型,总共3个像素层,所以三维的filt......
  • 【Linux详解】冯诺依曼架构 | 操作系统设计 | 斯坦福经典项目Pintos
    目录一.冯诺依曼体系结构(VonNeumannArchitecture)注意事项存储器的意义:缓冲数据流动示例二.操作系统(OperatingSystem)操作系统的概念操作系统的定位与目的操作系统的管理系统调用和库函数操作系统的管理:sum三.系统调用实现示例:Pintos项目Step1:进入ex......
  • GitHub星标破千!斯坦福大学的284个机器学习小抄(漫画中文版)
    说到人工智能必然要了解机器学习,从信息化软件,到电子商务,然后到高速发展互联网时代,到至今的云计算、大数据等,渗透到我们的生活、工作之中,在互联网的驱动下,人们更清晰的认识和使用数据,不仅仅是数据统计、分析,我们还强调数据挖掘、预测。机器学习就是对计算机一部分数据进行学习,......
  • 和斯坦福博士写代码的第 8个月
    不知不觉,和斯坦福博士在一起合作了8个月,记得在 和斯坦福博士写代码的一个月 这篇文章中,我谈了自己和他们合作第一个月的感受,今天再来聊聊和他们合作了8个月后最大的2个感受。语言是文化侵略的最好武器语言是文化侵略的最好武器在这8个月的合作中,感受最深的是语言是文化侵......