void RUDPObject::attach(IRUDPAdapter* adapter) { if(adapter == NULL) { RUDP_WARNING("adapter is NULL"); return ; } for(uint8_t i = 0; i < adapter_array_.size(); i ++) //关联本地的网络适配器 { if(adapter_array_[i] == adapter || i >= INVALID_ADAPTER_INDEX) //重复ATTACH { RUDP_WARNING("repeat attach adapter!!"); break; } //绑定 if(adapter_array_[i] == NULL) { adapter->set_index(i); adapter_array_[i] = adapter; RUDP_INFO("attach adapter, id = " << (uint16_t)i << ", local_addr = " << adapter->get_local_addr()); break; } } }
void RUDPSocket::send_data(uint64_t ack_seq_id, uint64_t cur_seq_id, const uint8_t* data, uint16_t data_size, uint64_t now_ts) { if(state_ != RUDP_CONNECTED || remote_rudp_id_ < 0 || data_size <= 0) { RUDP_WARNING("send data failed! rudp socket id = " << rudp_id_); return ; } RUDPHeadPacket head; head.msg_id_ = RUDP_DATA; head.remote_rudp_id_ = remote_rudp_id_; head.check_sum_ = check_sum_; RUDPData body; body.ack_seq_id_ = recv_buffer_.get_ack_id(); body.cur_seq_id_ = cur_seq_id; //body.data_.assign((const char*)data, data_size); //todo:减少一次拷贝 //设置一个最后发送ACK的时刻 recv_buffer_.set_send_last_ack_ts(now_ts); strm_.rewind(true); strm_ << local_title_ << head << body; //加入数据 strm_.push_data(data, data_size); RUDP()->send_udp(local_index_, strm_, remote_addr_); }
void RUDPObject::alloc_sockets() { int32_t array_size = socket_array_.size(); socket_array_.resize(array_size + RUDP_DEFAULT_POOL_SIZE); for(int32_t i = array_size; i < array_size + RUDP_DEFAULT_POOL_SIZE; ++ i) { if(i != 0) free_socket_ids_.insert(i); socket_array_[i] = NULL; } RUDP_WARNING("alloc " << RUDP_DEFAULT_POOL_SIZE << " rudp socket to pool!"); }
void RUDPSocket::process_data_ack(BinStream& strm, const Inet_Addr& remote_addr) { if(state_ != RUDP_CONNECTED) { RUDP_WARNING("process_data_ack, state_ != RUDP_CONNECTED"); return ; } //RUDP_DEBUG("on recv data ack, remote_addr = " << remote_addr); RUDPDataAck ack; strm >> ack; ccc_.on_ack(ack.ack_seq_id_); send_buffer_.on_ack(ack.ack_seq_id_); }
void RUDPSocket::process_data_nack(BinStream& strm, const Inet_Addr& remote_addr) { if(state_ != RUDP_CONNECTED) { RUDP_WARNING("process_data_nack, state_ != RUDP_CONNECTED"); return ; } RUDPDataNack nack; strm >> nack; send_buffer_.on_nack(nack.base_seq_, nack.loss_ids_); ccc_.on_loss(nack.base_seq_, nack.loss_ids_); ccc_.on_ack(nack.base_seq_); send_buffer_.on_ack(nack.base_seq_); }
void RUDPSocket::process_data(BinStream& strm, const Inet_Addr& remote_addr) { if(state_ != RUDP_CONNECTED) { RUDP_WARNING("process data, state != RUDP_CONNECTED"); return ; } RUDPData data; strm >> data; ccc_.on_ack(data.ack_seq_id_); send_buffer_.on_ack(data.ack_seq_id_); uint32_t data_size = 0; strm >> data_size; recv_buffer_.on_data(data.cur_seq_id_, (const uint8_t *)strm.get_rptr(), data_size); }
void RUDPSocket::process_keeplive_ack(BinStream& strm, const Inet_Addr& remote_addr) { RUDP_INFO("keeplive ack from " << remote_addr << ", rudp id = " << rudp_id_); if(state_ != RUDP_CONNECTED) { RUDP_WARNING("state != RUDP_CONNECTED"); return ; } keeplive_count_ = 0; PARSE_RUDP_MESSAGE(strm, RDUPKeepLive, ack, "parse keeplive ack failed!"); //计算RTT uint64_t now_ts = CBaseTimeValue::get_time_value().msec(); uint32_t rtt = static_cast<uint32_t>(now_ts > ack.timestamp_ ? (now_ts - ack.timestamp_) : 5); ccc_.set_rtt(rtt); RUDP_INFO("rtt = " << rtt << ", rudp socket id = " << rudp_id_); }
void RUDPSocket::send_nack(uint64_t base_seq_id, const LossIDArray& ids) { if(state_ != RUDP_CONNECTED || remote_rudp_id_ < 0) { RUDP_WARNING("send nack failed! rudp socket id = " << rudp_id_); return ; } RUDPHeadPacket head; head.msg_id_ = RUDP_DATA_NACK; head.remote_rudp_id_ = remote_rudp_id_; head.check_sum_ = check_sum_; RUDPDataNack nack; nack.base_seq_ = base_seq_id; nack.loss_ids_ = ids; strm_.rewind(true); strm_ << local_title_ << head << nack; RUDP()->send_udp(local_index_, strm_, remote_addr_); }
void RUDPSocket::send_ack(uint64_t ack_seq_id) { if(state_ != RUDP_CONNECTED || remote_rudp_id_ < 0) { RUDP_WARNING("send ack failed! rudp socket id = " << rudp_id_); return ; } RUDPHeadPacket head; head.msg_id_ = RUDP_DATA_ACK; head.remote_rudp_id_ = remote_rudp_id_; head.check_sum_ = check_sum_; RUDPDataAck ack; ack.ack_seq_id_ = ack_seq_id; strm_.rewind(true); strm_ << local_title_ << head << ack; //RUDP_DEBUG("send ack, rudp_id = " << rudp_id_ << ", seq = " << ack_seq_id); RUDP()->send_udp(local_index_, strm_, remote_addr_); }
void RUDPObject::process(IRUDPAdapter* adapter, BinStream& strm, const Inet_Addr& remote_addr) { uint8_t index = INVALID_ADAPTER_INDEX; if(adapter != NULL) index = adapter->get_index(); if(adapter_array_[index] == NULL) { RUDP_FATAL("adapter is not attach!!!"); return ; } PARSE_RUDP_HEAD(rudp_head, "parse rudp head failed!!"); RUDPSocket *rudp_session = get_socket(rudp_head.remote_rudp_id_); if(rudp_session != NULL) { rudp_session->process(rudp_head.msg_id_, rudp_head.check_sum_, strm, remote_addr); return ; } //处理SYN连接请求 if(rudp_head.msg_id_ == RUDP_SYN && rudp_head.remote_rudp_id_ == INVALID_RUDP_HANDLE) { PARSE_RUDP_MESSAGE(strm, RUDPSynPacket, syn, "parse syn failed!"); //在半开连接中找 rudp_session = find_by_peer_id(syn.local_rudp_id_, remote_addr); if(rudp_session == NULL) { int32_t new_rudp_id = create_socket(); if(new_rudp_id == INVALID_RUDP_HANDLE) { send_syn2(rudp_head.remote_rudp_id_, SYSTEM_SYN_ERROR, rudp_head.check_sum_, remote_addr, adapter); RUDP_INFO("send syn2 to " << remote_addr); return ; } if(this->bind(new_rudp_id, adapter->get_local_addr()) != 0) { free_sockets(new_rudp_id); send_syn2(rudp_head.remote_rudp_id_, SYSTEM_SYN_ERROR, rudp_head.check_sum_, remote_addr, adapter); RUDP_INFO("send syn2 to " << remote_addr); return ; } //建立远程SOCKET ID与本地SOCKET ID的关系,防止重复建立连接 RUDPPeerInfo info(syn.local_rudp_id_, remote_addr); peer_socket_ids_[info] = new_rudp_id; rudp_session = get_socket(new_rudp_id); rudp_session->set_check_sum(rudp_head.check_sum_); //提示上层EVENT HANDLE进行ACCEPT,可以在上层进行SOCKET属性设置 if(listener_ != NULL) listener_->rudp_accept_event(new_rudp_id); } //进行消息处理 rudp_session->process_syn(syn, remote_addr); } else { RUDP_WARNING("error msg, msg id = " << (uint16_t)rudp_head.msg_id_ << ", rudp id = " << rudp_head.remote_rudp_id_ << ", remote addr = "<< remote_addr); } }