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