/* * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
void TcpMessageRouteImpl::SendMessage(size_t size,
std::function<void()> on_received) {
task_queue_->PostTask([this, size, handler = std::move(on_received)] { // If we are currently sending a message we won't reset the connection, // we'll act as if the messages are sent in the same TCP stream. This is // intended to simulate recreation of a TCP session for each message // in the typical case while avoiding the complexity overhead of // maintaining multiple virtual TCP sessions in parallel. if (pending_.empty() && in_flight_.empty()) {
cwnd_ = 10;
ssthresh_ = INFINITY;
}
int64_t data_left = static_cast<int64_t>(size);
int64_t kMaxPacketSize = 1200;
int64_t kMinPacketSize = 4;
Message message{std::move(handler)}; while (data_left > 0) {
int64_t packet_size = std::min(data_left, kMaxPacketSize); int fragment_id = next_fragment_id_++;
pending_.push_back(MessageFragment{
fragment_id, static_cast<size_t>(std::max(kMinPacketSize, packet_size))});
message.pending_fragment_ids.insert(fragment_id);
data_left -= packet_size;
}
messages_.emplace_back(message);
SendPackets(clock_->CurrentTime());
});
}
void TcpMessageRouteImpl::OnRequest(TcpPacket packet_info) { for (auto it = messages_.begin(); it != messages_.end(); ++it) { if (it->pending_fragment_ids.count(packet_info.fragment.fragment_id) != 0) {
it->pending_fragment_ids.erase(packet_info.fragment.fragment_id); if (it->pending_fragment_ids.empty()) {
it->handler();
messages_.erase(it);
} break;
}
} const size_t kAckPacketSize = 20;
response_route_.SendPacket(kAckPacketSize, packet_info);
}
void TcpMessageRouteImpl::OnResponse(TcpPacket packet_info, Timestamp at_time) { auto it = in_flight_.find(packet_info.sequence_number); if (it != in_flight_.end()) {
last_rtt_ = at_time - packet_info.send_time;
in_flight_.erase(it);
} auto lost_end = in_flight_.lower_bound(packet_info.sequence_number); for (auto lost_it = in_flight_.begin(); lost_it != lost_end;
lost_it = in_flight_.erase(lost_it)) {
pending_.push_front(lost_it->second.fragment);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.