Google quiche客户端socket读写模型

2023-10-13  本文已影响0人  JeffreyLau

1、前言

2、QuicClientDefaultNetworkHelper定义

3、QuicClientBase::NetworkHelper接口的定义及实现

class QuicClientBase : public QuicSession::Visitor {
 public:
  // An interface to various network events that the QuicClient will need to
  // interact with.
  class NetworkHelper {
   public:
    virtual ~NetworkHelper();

    // Runs one iteration of the event loop.
    // 用于socket io 循环loop
    virtual void RunEventLoop() = 0;

    // Used during initialization: creates the UDP socket FD, sets socket
    // options, and binds the socket to our address.
    // 创建一个udp socket,并将socket fd 向事件循环注册,通过IO监听该socket
    virtual bool CreateUDPSocketAndBind(QuicSocketAddress server_address,
                                        QuicIpAddress bind_to_address,
                                        int bind_to_port) = 0;

    // Unregister and close all open UDP sockets.
    // 关闭一个socket,并将socket从io 事件循环中注销
    virtual void CleanUpAllUDPSockets() = 0;

    // If the client has at least one UDP socket, return address of the latest
    // created one. Otherwise, return an empty socket address.
    virtual QuicSocketAddress GetLatestClientAddress() const = 0;

    // Creates a packet writer to be used for the next connection.
    // 创建一个socket writer,用于往socket写入数据
    virtual QuicPacketWriter* CreateQuicPacketWriter() = 0;
  };
  ....
}
void QuicClientDefaultNetworkHelper::RunEventLoop() {
  quiche::QuicheRunSystemEventLoopIteration();
  event_loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(50));
}
bool QuicClientDefaultNetworkHelper::CreateUDPSocketAndBind(
    QuicSocketAddress server_address, QuicIpAddress bind_to_address,
    int bind_to_port) {
  SocketFd fd = CreateUDPSocket(server_address, &overflow_supported_);
  if (fd == kInvalidSocketFd) {
    return false;
  }
  auto closer = absl::MakeCleanup([fd] { (void)socket_api::Close(fd); });

  ......

  if (event_loop_->RegisterSocket(
          fd, kSocketEventReadable | kSocketEventWritable, this)) {
    fd_address_map_[fd] = client_address;
    std::move(closer).Cancel();
    return true;
  }
  return false;
}
void QuicClientDefaultNetworkHelper::CleanUpAllUDPSockets() {
  for (std::pair<int, QuicSocketAddress> fd_address : fd_address_map_) {
    CleanUpUDPSocketImpl(fd_address.first);
  }
  fd_address_map_.clear();
}

void QuicClientDefaultNetworkHelper::CleanUpUDPSocketImpl(SocketFd fd) {
  if (fd != kInvalidSocketFd) {
    bool success = event_loop_->UnregisterSocket(fd);
    QUICHE_DCHECK(success || fds_unregistered_externally_);
    absl::Status rc = socket_api::Close(fd);
    QUICHE_DCHECK(rc.ok()) << rc;
  }
}
QuicPacketWriter* QuicClientDefaultNetworkHelper::CreateQuicPacketWriter() {
  if (event_loop_->SupportsEdgeTriggered()) {
    return new QuicDefaultPacketWriter(GetLatestFD());
  } else {
    return new LevelTriggeredPacketWriter(GetLatestFD(), event_loop_);
  }
}

4、QuicSocketEventListener接口的定义及实现


class QUICHE_NO_EXPORT QuicSocketEventListener {
 public:
  virtual ~QuicSocketEventListener() = default;

  virtual void OnSocketEvent(QuicEventLoop* event_loop, SocketFd fd,
                             QuicSocketEventMask events) = 0;
};
void QuicClientDefaultNetworkHelper::OnSocketEvent(
    QuicEventLoop* /*event_loop*/, QuicUdpSocketFd fd,
    QuicSocketEventMask events) {
  if (events & kSocketEventReadable) {
    QUIC_DVLOG(1) << "Read packets on kSocketEventReadable";
    int times_to_read = max_reads_per_event_loop_;
    bool more_to_read = true;
    QuicPacketCount packets_dropped = 0;
    while (client_->connected() && more_to_read && times_to_read > 0) {
      // 读取udp包,并将包转换成QuicReceivedPacket包,然后通过ProcessPacketInterface::ProcessPacket
      // 对报文进行处理
      more_to_read = packet_reader_->ReadAndDispatchPackets(
          fd, GetLatestClientAddress().port(), *client_->helper()->GetClock(),
          this, overflow_supported_ ? &packets_dropped : nullptr);
      --times_to_read;
    }
    ....
  }
  if (client_->connected() && (events & kSocketEventWritable)) {
    client_->writer()->SetWritable();
    client_->session()->connection()->OnCanWrite();
  }
}

5、ProcessPacketInterface接口的定义及实现

// A class to process each incoming packet.
class QUIC_NO_EXPORT ProcessPacketInterface {
 public:
  virtual ~ProcessPacketInterface() {}
  virtual void ProcessPacket(const QuicSocketAddress& self_address,
                             const QuicSocketAddress& peer_address,
                             const QuicReceivedPacket& packet) = 0;
};
void QuicClientDefaultNetworkHelper::ProcessPacket(
    const QuicSocketAddress& self_address,
    const QuicSocketAddress& peer_address, const QuicReceivedPacket& packet) {
  client_->session()->ProcessUdpPacket(self_address, peer_address, packet);
}
void QuicSession::ProcessUdpPacket(const QuicSocketAddress& self_address,
                                   const QuicSocketAddress& peer_address,
                                   const QuicReceivedPacket& packet) {
  QuicConnectionContextSwitcher cs(connection_->context());
  connection_->ProcessUdpPacket(self_address, peer_address, packet);
}

总结

上一篇 下一篇

猜你喜欢

热点阅读