void RUDPSocket::process_syn2(BinStream& strm, const Inet_Addr& remote_addr) { RUDP_INFO("recv syn2 from " << remote_addr << ", rudp id = " << rudp_id_); PARSE_RUDP_MESSAGE(strm, RUDPSyn2Packet, syn2, "parse syn2 failed!"); if(state_ == RUDP_CONNECTING) { if(syn2.syn2_result_ != 0x00) //连接异常 { RUDP_INFO("syn failed! syn2.syn2_result_ = " << (uint16_t)syn2.syn2_result_); if(event_handler_ != NULL) { RUDP_INFO("state = RUDP_FIN2_STATE, rudp id = " << rudp_id_); set_state(RUDP_FIN2_STATE); event_handler_->rudp_exception_event(rudp_id_); } else { RUDP_INFO("state = RUDP_CLOSE, rudp id = " << rudp_id_); set_state(RUDP_CLOSE); } return ; } //设置接收BUFF的初始化 //ccc_.init(syn2.start_seq_ - 1); recv_buffer_.set_first_seq(syn2.start_seq_); //设置连接信息 remote_addr_ = remote_addr; remote_rudp_id_ = syn2.local_rudp_id_; //计算RTT uint64_t now_ts = CBaseTimeValue::get_time_value().msec(); uint32_t rtt = static_cast<uint32_t>(now_ts > syn2.remote_ts_ ? (now_ts - syn2.remote_ts_) : 5); recv_buffer_.set_send_last_ack_ts(now_ts); ccc_.set_rtt(rtt); RUDP_INFO("syn succ, sart seq = " << syn2.start_seq_ << ", remote_rudp_id = " << remote_rudp_id_ << ", rtt = " << rtt); RUDP_INFO("state = RUDP_CONNECTED, rudp id = " << rudp_id_); set_state(RUDP_CONNECTED); RUDP_DEBUG("send syn ack, rudp socket id = " << rudp_id_); send_syn_ack(0, syn2.local_ts_); //触发一个写事件 if(event_handler_ != NULL) event_handler_->rudp_output_event(rudp_id_); heart_ts_ = now_ts; } else if(state_ == RUDP_CONNECTED) { RUDP_DEBUG("send syn ack, rudp socket id = " << rudp_id_); send_syn_ack(0, syn2.local_ts_); } }
int32_t RUDPSocket::handle_timeout(const void *act, uint32_t timer_id) { if(timer_id_ != timer_id) return 0; timer_id_= 0; //解决状态定时的问题,尤其是报文发送 switch(state_) { case RUDP_CONNECTING: if(send_count_ < SYN_MAX_COUNT) { send_syn(); set_timer(CONNECT_DELAY); RUDP_DEBUG("resend syn, rudp socket id = " << rudp_id_); send_count_ ++; } else //连接超时 { RUDP_INFO("connecting timeout! state = RUDP_FIN2_STATE, rudp id = " << rudp_id_); set_state(RUDP_FIN2_STATE); if(event_handler_ != NULL) event_handler_->rudp_exception_event(rudp_id_); else { RUDP_INFO("state = RUDP_CLOSE, rudp id = " << rudp_id_); set_state(RUDP_CLOSE); } } break; case RUDP_FIN_STATE: if(send_count_ < FIN_MAX_COUNT) { RUDP_DEBUG("resend fin, rudp socket id = " << rudp_id_); send_fin(); set_timer(ccc_.get_rtt() + TIMER_MIN_DELAY); send_count_ ++; } else { RUDP_INFO("fin timeout, state = RUDP_CLOSE, rudp id = " << rudp_id_); set_state(RUDP_CLOSE); } break; } return 0; }
void RUDPCCCObject::on_ack(uint64_t ack_seq) { if(ack_seq <= last_ack_id_) { return; } uint32_t space = (uint32_t)(ack_seq - last_ack_id_); if(slow_start_) //慢启动窗口决策 { snd_cwnd_ += space; if(snd_cwnd_ >= max_cwnd_) { slow_start_ = false; RUDP_INFO("ccc stop slow_start, snd_cwnd = " << snd_cwnd_); snd_cwnd_ = max_cwnd_; } RUDP_DEBUG("send window size = " << snd_cwnd_); } else //平衡状态 { if (recv_count_ / 2 < resend_count_) //出现丢包,不做加速 loss_flag_ = false; else if(resend_count_ == 0) //加速,快速恢复 { snd_cwnd_ = (uint32_t)(snd_cwnd_ + (snd_cwnd_ >> 3)); snd_cwnd_ = core_min(max_cwnd_, snd_cwnd_); loss_flag_ = false; } }
void RUDPSocket::reset() { if(state_ != RUDP_IDLE) { RUDP_DEBUG("state = RUDP_IDLE, rudp id = " << rudp_id_); state_ = RUDP_IDLE; } rudp_id_ = -1; local_index_ = INVALID_ADAPTER_INDEX; local_title_ = 0; remote_rudp_id_ = INVALID_RUDP_HANDLE; heart_ts_ = CBaseTimeValue::get_time_value().msec(); keeplive_intnal_ = DEFAULT_KEEPLIVE; keeplive_count_ = 0; timeout_count_ = DEFAULT_TIMEOUT_COUNT; event_handler_ = NULL; error_code_ = RUDP_SUCCESS; send_count_ = 0; cancel_timer(); ccc_.reset(); send_buffer_.reset(); recv_buffer_.reset(); check_sum_ = 0; }
//正常关闭RUDP SOCKET void RUDPSocket::close() { switch(state_) { case RUDP_CONNECTING: case RUDP_CONNECTED: if(event_handler_ != NULL) { event_handler_->rudp_close_event(rudp_id_); } //发送SYN RUDP_INFO("close rudp socket, state = RUDP_FIN_STATE, rudp id = " << rudp_id_); set_state(RUDP_FIN_STATE); RUDP_DEBUG("send fin, rudp socket id = " << rudp_id_); send_fin(); set_timer(ccc_.get_rtt() + TIMER_MIN_DELAY); send_count_ ++; break; case RUDP_FIN2_STATE: set_state(RUDP_CLOSE); break; } }
void RUDPSocket::process_syn(RUDPSynPacket& syn, const Inet_Addr& remote_addr) { RUDP_INFO("recv syn from " << remote_addr << ", rudp id = " << rudp_id_); if(state_ == RUDP_IDLE && rudp_id_ != INVALID_RUDP_HANDLE) { uint64_t now_timer = CBaseTimeValue::get_time_value().msec(); //初始化接收SEQ recv_buffer_.set_first_seq(syn.start_seq_); recv_buffer_.set_send_last_ack_ts(now_timer); ccc_.init(send_buffer_.get_buffer_seq() - 1); //设置连接信息 remote_addr_ = remote_addr; remote_rudp_id_ = syn.local_rudp_id_; RUDP_INFO("sart seq = " << syn.start_seq_ << ", remote_rudp_id = " << remote_rudp_id_); RUDP_DEBUG("send syn2, rudp socket id = " << rudp_id_); send_syn2(0, syn.local_ts_); RUDP_INFO("state = RUDP_CONNECTED, rudp id = " << rudp_id_); set_state(RUDP_CONNECTED); //发送一个KEEPLIVE RUDP_DEBUG("send keeplive, rudp socket id =" << rudp_id_); send_keeplive(now_timer); } else if(state_ == RUDP_CONNECTING || state_ == RUDP_CONNECTED) { RUDP_INFO("send syn2, rudp socket id = " << rudp_id_); send_syn2(0, syn.local_ts_); } else { RUDP_DEBUG("send syn2(ERROR_SYN_STATE), rudp socket id = " << rudp_id_); send_syn2(ERROR_SYN_STATE, syn.local_ts_); RUDP_INFO("state = RUDP_CLOSE, rudp id = " << rudp_id_); set_state(RUDP_CLOSE); } }
//强制关闭RUDP SOCKET void RUDPSocket::force_close() { switch(state_) { case RUDP_CONNECTING: case RUDP_CONNECTED: RUDP_DEBUG("send fin, rudp socket id = " << rudp_id_); for(uint8_t i = 0; i < 6; i ++) //直接发送3个fin send_fin(); case RUDP_FIN2_STATE: RUDP_INFO("state = RUDP_CLOSE"); set_state(RUDP_CLOSE); break; } }
void RUDPCCCObject::on_timer(uint64_t now_ts) { uint32_t delay = core_max(rtt_ / 8, 50); if (now_ts >= prev_on_ts_ + delay) //10个RTT决策一次 { print_count_ ++; if(print_count_ % 4 == 0) { RUDP_DEBUG("send window size = " << snd_cwnd_ << ",rtt = " << rtt_ << ",rtt_var = " << rtt_var_ << ",resend = " << resend_count_); set_max_cwnd(rtt_); } if(slow_start_) //停止慢启动过程 { if(print_count_ > 10) { slow_start_ = false; RUDP_INFO("ccc stop slow_start, snd_cwnd = " << snd_cwnd_); } } else { if (recv_count_ > (snd_cwnd_ * delay * 7 / (rtt_ * 8))) { snd_cwnd_ = (uint32_t)(snd_cwnd_ + core_max(8,(snd_cwnd_ / 8))); snd_cwnd_ = core_min(max_cwnd_, snd_cwnd_); loss_flag_ = false; } else if (recv_count_ < snd_cwnd_ * delay * 5 / (rtt_ * 8)){ snd_cwnd_ = (uint32_t)(snd_cwnd_ - (snd_cwnd_ / 16)); snd_cwnd_ = core_max(min_cwnd_, snd_cwnd_); loss_flag_ = true; } else if (rtt_var_ > 30 && resend_count_ >= core_max(8, snd_cwnd_ * delay * 3 / (8 * rtt_))){ snd_cwnd_ = (uint32_t)(snd_cwnd_ - (snd_cwnd_ / 10)); snd_cwnd_ = core_max(min_cwnd_, snd_cwnd_); loss_flag_ = true; } resend_count_ = 0; } recv_count_ = 0; prev_on_ts_ = now_ts; } }
void RUDPSocket::heartbeat() { if(state_ != RUDP_CONNECTED) return ; uint64_t now_ts = CBaseTimeValue::get_time_value().msec(); //心跳计数 if(now_ts > heart_ts_ + keeplive_intnal_) { keeplive_count_ ++; if(keeplive_count_ > timeout_count_) //超时 { RUDP_ERROR("keep live timeout, rudp socket id = " << rudp_id_); if(event_handler_ != NULL) //通知上层异常 { RUDP_INFO("state = RUDP_FIN2_STATE"); set_state(RUDP_FIN2_STATE); event_handler_->rudp_exception_event(rudp_id_); return ; } else { RUDP_INFO("state = RUDP_CLOSE"); set_state(RUDP_CLOSE); return ; } } else//发送KEEPLIVE { RUDP_DEBUG("send keeplive, rudp socket id =" << rudp_id_); send_keeplive(now_ts); } } //模块心跳 ccc_.on_timer(now_ts); recv_buffer_.on_timer(now_ts, ccc_.get_rtt_var()); send_buffer_.on_timer(now_ts); }
int32_t RUDPSocket::connect(const Inet_Addr& remote_addr) { if(rudp_id_ == INVALID_RUDP_HANDLE || state_ != RUDP_IDLE || local_index_ == 255 || remote_rudp_id_ != INVALID_RUDP_HANDLE) { RUDP_FATAL("rudp connect failed! rudp socket id = " << rudp_id_); error_code_ = RUDP_CONNECT_FAIL; return -1; } remote_addr_ = remote_addr; check_sum_ = rand() % 65536; //产生一个会话的CHECK SUM RUDP_INFO("state = RUDP_CONNECTING, rudp id = " << rudp_id_ << ", remote addr = " << remote_addr_); set_state(RUDP_CONNECTING); RUDP_DEBUG("send syn, rudp socket id = " << rudp_id_); send_syn(); ccc_.init(send_buffer_.get_buffer_seq() - 1); set_timer(CONNECT_DELAY); send_count_ ++; return 0; }