refactor timer
This commit is contained in:
parent
1764b933de
commit
ea7b9605a4
@ -20,9 +20,8 @@ using namespace std;
|
|||||||
TCPSender::TCPSender(const size_t capacity, const uint16_t retx_timeout, const std::optional<WrappingInt32> fixed_isn)
|
TCPSender::TCPSender(const size_t capacity, const uint16_t retx_timeout, const std::optional<WrappingInt32> fixed_isn)
|
||||||
: _isn(fixed_isn.value_or(WrappingInt32{random_device()()}))
|
: _isn(fixed_isn.value_or(WrappingInt32{random_device()()}))
|
||||||
, _initial_retransmission_timeout{retx_timeout}
|
, _initial_retransmission_timeout{retx_timeout}
|
||||||
, _stream(capacity) {
|
, _stream(capacity)
|
||||||
_timer.reinit(_initial_retransmission_timeout);
|
, _timer(retx_timeout) {}
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t TCPSender::bytes_in_flight() const { return _next_seqno - _unack_seqno; }
|
uint64_t TCPSender::bytes_in_flight() const { return _next_seqno - _unack_seqno; }
|
||||||
|
|
||||||
@ -50,6 +49,7 @@ void TCPSender::fill_window() {
|
|||||||
_next_seqno += seg.length_in_sequence_space();
|
_next_seqno += seg.length_in_sequence_space();
|
||||||
hdr.syn = false;
|
hdr.syn = false;
|
||||||
hdr.seqno = next_seqno();
|
hdr.seqno = next_seqno();
|
||||||
|
_timer.start();
|
||||||
if (sendptr >= data.size())
|
if (sendptr >= data.size())
|
||||||
break;
|
break;
|
||||||
payload = data.substr(sendptr, TCPConfig::MAX_PAYLOAD_SIZE);
|
payload = data.substr(sendptr, TCPConfig::MAX_PAYLOAD_SIZE);
|
||||||
@ -65,8 +65,8 @@ void TCPSender::fill_window() {
|
|||||||
_segments_out.push(seg);
|
_segments_out.push(seg);
|
||||||
_outstandings.push(seg);
|
_outstandings.push(seg);
|
||||||
_next_seqno += seg.length_in_sequence_space();
|
_next_seqno += seg.length_in_sequence_space();
|
||||||
|
_timer.start();
|
||||||
}
|
}
|
||||||
_timer.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! \param ackno The remote receiver's ackno (acknowledgment number)
|
//! \param ackno The remote receiver's ackno (acknowledgment number)
|
||||||
@ -81,7 +81,7 @@ void TCPSender::ack_received(const WrappingInt32 ackno, const uint16_t window_si
|
|||||||
if (abs_ackno >= _unack_seqno + _outstandings.front().length_in_sequence_space()) {
|
if (abs_ackno >= _unack_seqno + _outstandings.front().length_in_sequence_space()) {
|
||||||
_unack_seqno += _outstandings.front().length_in_sequence_space();
|
_unack_seqno += _outstandings.front().length_in_sequence_space();
|
||||||
_outstandings.pop();
|
_outstandings.pop();
|
||||||
_timer.reinit(_initial_retransmission_timeout);
|
_timer.reset_init(_initial_retransmission_timeout);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -95,18 +95,19 @@ void TCPSender::ack_received(const WrappingInt32 ackno, const uint16_t window_si
|
|||||||
|
|
||||||
//! \param[in] ms_since_last_tick the number of milliseconds since the last call to this method
|
//! \param[in] ms_since_last_tick the number of milliseconds since the last call to this method
|
||||||
void TCPSender::tick(const size_t ms_since_last_tick) {
|
void TCPSender::tick(const size_t ms_since_last_tick) {
|
||||||
if (!_timer.started())
|
if (!_timer.is_started())
|
||||||
return;
|
return;
|
||||||
_timer.count_down(ms_since_last_tick);
|
_timer.tick(ms_since_last_tick);
|
||||||
if (!_timer.expired())
|
if (!_timer.is_expired())
|
||||||
return;
|
return;
|
||||||
_segments_out.push(_outstandings.front());
|
_segments_out.push(_outstandings.front());
|
||||||
if (_window_size > 0)
|
if (_window_size > 0)
|
||||||
_timer.consec_retrans();
|
_timer.retransmit();
|
||||||
_timer.reset();
|
_timer.reset();
|
||||||
|
_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int TCPSender::consecutive_retransmissions() const { return _timer.consec_retrans_count(); }
|
unsigned int TCPSender::consecutive_retransmissions() const { return _timer.consecutive_retransmissions(); }
|
||||||
|
|
||||||
void TCPSender::send_empty_segment() {
|
void TCPSender::send_empty_segment() {
|
||||||
TCPHeader hdr;
|
TCPHeader hdr;
|
||||||
|
|||||||
@ -14,36 +14,39 @@
|
|||||||
//! God knows what this class does
|
//! God knows what this class does
|
||||||
class TCPTimer {
|
class TCPTimer {
|
||||||
private:
|
private:
|
||||||
size_t RTO{0};
|
size_t RTO;
|
||||||
size_t rt_count{0};
|
size_t _cr_count{0};
|
||||||
size_t ti_count{0};
|
size_t _ti_count;
|
||||||
bool timer_on{false};
|
bool _is_started{false};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TCPTimer() = default;
|
TCPTimer(uint32_t initial_retransmission_timeout)
|
||||||
void reinit(uint32_t initial_RTO) {
|
: RTO(initial_retransmission_timeout), _ti_count(initial_retransmission_timeout) {}
|
||||||
RTO = initial_RTO;
|
void reset_init(uint32_t initial_retransmission_timeout) {
|
||||||
ti_count = RTO;
|
RTO = initial_retransmission_timeout;
|
||||||
rt_count = 0;
|
_ti_count = RTO;
|
||||||
timer_on = false;
|
_cr_count = 0;
|
||||||
|
_is_started = false;
|
||||||
}
|
}
|
||||||
void reset() { ti_count = RTO; }
|
void reset() {
|
||||||
size_t cur_RTO() const { return RTO; }
|
_ti_count = RTO;
|
||||||
void start() { timer_on = true; }
|
_is_started = false;
|
||||||
bool started() const { return timer_on; }
|
}
|
||||||
void stop() { timer_on = false; }
|
void start() { _is_started = true; }
|
||||||
bool expired() const { return ti_count == 0; }
|
void stop() { _is_started = false; }
|
||||||
void count_down(size_t milli_sec) {
|
void tick(size_t milli_sec) {
|
||||||
if (ti_count >= milli_sec)
|
if (_ti_count >= milli_sec)
|
||||||
ti_count -= milli_sec;
|
_ti_count -= milli_sec;
|
||||||
else
|
else
|
||||||
ti_count = 0;
|
_ti_count = 0;
|
||||||
}
|
}
|
||||||
void consec_retrans() {
|
void retransmit() {
|
||||||
rt_count++;
|
_cr_count++;
|
||||||
RTO <<= 1;
|
RTO <<= 1;
|
||||||
}
|
}
|
||||||
size_t consec_retrans_count() const { return rt_count; }
|
bool is_started() const { return _is_started; }
|
||||||
|
bool is_expired() const { return _ti_count == 0; }
|
||||||
|
size_t consecutive_retransmissions() const { return _cr_count; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//! \brief The "sender" part of a TCP implementation.
|
//! \brief The "sender" part of a TCP implementation.
|
||||||
@ -73,7 +76,7 @@ class TCPSender {
|
|||||||
//! current window size, default (and at least) should be 1 byte according to the handout
|
//! current window size, default (and at least) should be 1 byte according to the handout
|
||||||
uint16_t _window_size{1};
|
uint16_t _window_size{1};
|
||||||
std::queue<TCPSegment> _outstandings{};
|
std::queue<TCPSegment> _outstandings{};
|
||||||
TCPTimer _timer{};
|
TCPTimer _timer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Initialize a TCPSender
|
//! Initialize a TCPSender
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user