Revolver源码解析之——RUDP Socket类实现解析

1、类间关系类图。

【1】类间关系。


【2】类图。


2、Socket的完成的概功能解析。

2.1、模仿TCP绑定端口并监听端口。

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;
}

[1].重置rudp_socket类的各个成员变量。

[2].打开socket。

int32_t RUDPSocket::open(int32_t rudp_id)
{
    reset();

    rudp_id_ = rudp_id;

    return 0;
}

[3].绑定。

int32_t RUDPSocket::bind(uint8_t index, uint8_t title)
{
    if(rudp_id_ == -1 || state_ != RUDP_IDLE)
    {
        RUDP_FATAL("rudp socket bind failed!");
        error_code_ = RUDP_BIND_FAIL;
        return -1;
    }

    local_index_ = index;
    local_title_ = title;

    return 0;
}

[4].与远端建立连接。

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;
}

主动建立连接的一端向被动接受连接的一端发送SYN包(主动建立连接包)。

[5].被动接受连接的一端处理SYN包。

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);
    }
}

[6].被动接受连接的一端发送SYN对应的返回包,即SYN2包。

void RUDPSocket::send_syn2(uint8_t result, uint64_t remote_ts)
{
    RUDPHeadPacket head;
    head.msg_id_ = RUDP_SYN2;
    head.remote_rudp_id_ = remote_rudp_id_;
    head.check_sum_ = check_sum_;

    RUDPSyn2Packet syn2;
    syn2.version_ = RUDP_VERSION;
    syn2.local_rudp_id_ = rudp_id_;
    syn2.local_ts_ = CBaseTimeValue::get_time_value().msec();
    syn2.remote_ts_ = remote_ts;
    syn2.syn2_result_ = result;
    syn2.max_segment_size_ = MAX_SEGMENT_SIZE;
    syn2.start_seq_ = send_buffer_.get_buffer_seq();

    strm_.rewind(true);
    strm_ << local_title_ << head << syn2;

    for(uint8_t i = 0; i < 3; ++i)
        RUDP()->send_udp(local_index_, strm_, remote_addr_);
}

[7].主动建立连接的一端处理SYN2包。

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_);
    }
}

[8].主动建立连接的端发送SYN2的ACK包。

void RUDPSocket::send_syn_ack(uint8_t result , uint64_t remote_ts)
{
    RUDPHeadPacket head;
    head.msg_id_ = RUDP_SYN_ACK;
    head.remote_rudp_id_ = remote_rudp_id_;
    head.check_sum_ = check_sum_;

    RUDPSyn2AckPacket syn_ack;
    syn_ack.result_ = result;
    syn_ack.remote_ts_ = remote_ts;

    strm_.rewind(true);
    strm_ << local_title_ << head << syn_ack;

    RUDP()->send_udp(local_index_, strm_, remote_addr_);
}

经历了上述步骤,一个RUDP连接正式建立。

2.2 发送数据与心跳包。

[1].发送数据。

int32_t RUDPSocket::send(const uint8_t* data, int32_t data_size)
{
    if(state_ != RUDP_CONNECTED || data_size <= 0)
    {
		RUDP_FATAL("send failed! state_ != RUDP_CONNECTED or data size = 0, rudp id = " << rudp_id_ << ", state =" << state_);
        error_code_ = RUDP_SEND_ERROR;
        return -1;
    }

    int32_t ret = send_buffer_.send(data, data_size);
    if(ret <= 0)
    {
        RUDP_INFO("send buffer is full, rudp socket id = " << rudp_id_);
        error_code_ = RUDP_SEND_EAGIN;
    }

    return ret;
}

[2].处理接收的数据片。

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::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_);
}

[3].发送可靠数据的确认。

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_);
}

[4].发送nack包。

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_);
}

[5].处理nack包。

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_);
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值