/* * Copyright 2004 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.
*/
AsyncUDPSocket::AsyncUDPSocket(Socket* socket) : socket_(socket) {
sequence_checker_.Detach(); // The socket should start out readable but not writable.
socket_->SignalReadEvent.connect(this, &AsyncUDPSocket::OnReadEvent);
socket_->SignalWriteEvent.connect(this, &AsyncUDPSocket::OnWriteEvent);
}
int AsyncUDPSocket::Send(constvoid* pv,
size_t cb, const rtc::PacketOptions& options) {
rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis(),
options.info_signaled_after_sent);
CopySocketInformationToPacketInfo(cb, *this, &sent_packet.info); int ret = socket_->Send(pv, cb);
SignalSentPacket(this, sent_packet); return ret;
}
int AsyncUDPSocket::SendTo(constvoid* pv,
size_t cb, const SocketAddress& addr, const rtc::PacketOptions& options) {
rtc::SentPacket sent_packet(options.packet_id, rtc::TimeMillis(),
options.info_signaled_after_sent);
CopySocketInformationToPacketInfo(cb, *this, &sent_packet.info); if (has_set_ect1_options_ != options.ecn_1) { // It is unclear what is most efficient, setting options on every sent // packet or when changed. Potentially, can separate send sockets be used? // This is the easier implementation. if (socket_->SetOption(Socket::Option::OPT_SEND_ECN,
options.ecn_1 ? 1 : 0) == 0) {
has_set_ect1_options_ = options.ecn_1;
}
} int ret = socket_->SendTo(pv, cb, addr);
SignalSentPacket(this, sent_packet); return ret;
}
int AsyncUDPSocket::Close() { return socket_->Close();
}
Socket::ReceiveBuffer receive_buffer(buffer_); int len = socket_->RecvFrom(receive_buffer); if (len < 0) { // An error here typically means we got an ICMP error in response to our // send datagram, indicating the remote address was unreachable. // When doing ICE, this kind of thing will often happen. // TODO: Do something better like forwarding the error to the user.
SocketAddress local_addr = socket_->GetLocalAddress();
RTC_LOG(LS_INFO) << "AsyncUDPSocket[" << local_addr.ToSensitiveString()
<< "] receive failed with error " << socket_->GetError(); return;
} if (len == 0) { // Spurios wakeup. return;
}
if (!receive_buffer.arrival_time) { // Timestamp from socket is not available.
receive_buffer.arrival_time = webrtc::Timestamp::Micros(rtc::TimeMicros());
} else { if (!socket_time_offset_) { // Estimate timestamp offset from first packet arrival time.
socket_time_offset_ = webrtc::Timestamp::Micros(rtc::TimeMicros()) -
*receive_buffer.arrival_time;
}
*receive_buffer.arrival_time += *socket_time_offset_;
}
NotifyPacketReceived(
ReceivedPacket(receive_buffer.payload, receive_buffer.source_address,
receive_buffer.arrival_time, receive_buffer.ecn));
}
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.