标签:
在RUDP模块中,所有发送的数据被定义成RUDPRecvSegment 和 RUDPSendSegment结构,其中RUDPSendSegment是发送块定义,RUDPRecvSegment 是接收块定义。如下:
//发送数据片
typedef struct tagRUDPSendSegment
{
uint64_t seq_; //块序号
uint64_t push_ts_; //进入发送队列的时刻
uint64_t last_send_ts_; //最后一次发送的时刻
uint16_t send_count_; //发送的次数
uint8_t data_[MAX_SEGMENT_SIZE]; //块数据
uint16_t data_size_; //块数据长度
}RUDPSendSegment;
typedef struct tagRUDPRecvSegment
{
uint64_t seq_; //块序号
uint8_t data_[MAX_SEGMENT_SIZE]; //块数据
uint16_t data_size_; //块数据长度
}RUDPRecvSegment;
ObjectPool<RUDPSendSegment, RUDP_SEGMENT_POOL_SIZE> SENDSEGPOOL; ObjectPool<RUDPRecvSegment, RUDP_SEGMENT_POOL_SIZE> RECVSEGPOOL; #define GAIN_SEND_SEG(seg) RUDPSendSegment* seg = SENDSEGPOOL.pop_obj(); seg->reset() #define RETURN_SEND_SEG(seg) if(seg != NULL) SENDSEGPOOL.push_obj(seg) #define GAIN_RECV_SEG(seg) RUDPRecvSegment* seg = RECVSEGPOOL.pop_obj(); seg->reset() #define RETURN_RECV_SEG(seg) if(seg != NULL) RECVSEGPOOL.push_obj(seg)
几个宏是作为块申请和释放的宏。以上就是块的定义介绍,更具体的只有去查看相关源代码了。
发送缓冲区,定义如下:
class RUDPSendBuffer
{
public:
...
//发送数据接口
int32_t send(const uint8_t* data, int32_t data_size);
//ACK处理
void on_ack(uint64_t ack_seq);
//NACK处理
void on_nack(uint64_t base_seq, const LossIDArray& loss_ids);
//定时器接口
void on_timer(uint64_t now_ts);
//检查BUFFER是否可以写入数据
void check_buffer();
...
public:
uint64_t get_buffer_seq() {return buffer_seq_;};
//设置NAGLE算法
void set_nagle(bool nagle = true){nagle_ = nagle;};
bool get_nagle() const {return nagle_;};
//设置发送缓冲区的大小
void set_buffer_size(int32_t buffer_size){buffer_size_ = buffer_size;};
int32_t get_buffer_size() const {return buffer_size_;};
...
protected:
IRUDPNetChannel* net_channel_;
//正在发送的数据片
SendWindowMap send_window_;
//正在发送的报文的丢包集合
LossIDSet loss_set_;
//等待发送的数据片
SendDataList send_data_;
//发送缓冲区的大小
int32_t buffer_size_;
//当前缓冲数据的大小
int32_t buffer_data_size_;
//当前BUFFER中最大的SEQ
uint64_t buffer_seq_;
//当前WINDOW中最大的SEQ
uint64_t cwnd_max_seq_;
//接收端最大的SEQ
uint64_t dest_max_seq_;
//速度控制器
RUDPCCCObject* ccc_;
//是否启动NAGLE算法
bool nagle_;
}
int32_t RUDPSendBuffer::send(const uint8_t* data, int32_t data_size)
{
int32_t copy_pos = 0;
int32_t copy_size = 0;
uint8_t* pos = (uint8_t *)data;
uint64_t now_timer = CBaseTimeValue::get_time_value().msec();
if(!send_data_.empty()) //拼接报文,让其接近MAX_SEGMENT_SIZE
{
//取出send_data_中的最后一片,如果它没有达到MAX_SEGMENT_SIZE,数据追加到MAX_SEGMENT_SIZE大小为止。
RUDPSendSegment* last_seg = send_data_.back();
if(last_seg != NULL && last_seg->data_size_ < MAX_SEGMENT_SIZE)
{
copy_size = MAX_SEGMENT_SIZE - last_seg->data_size_;
if( copy_size > data_size)
copy_size = data_size;
memcpy(last_seg->data_ + last_seg->data_size_, pos, copy_size);
copy_pos += copy_size;
pos += copy_size;
last_seg->data_size_ += copy_size;
}
}
//剩余数据分成MAX_SEGMENT_SIZE为单位的若干分片
while(copy_pos < data_size)
{
GAIN_SEND_SEG(last_seg);
//设置初始化的的时刻
last_seg->push_ts_ = now_timer; //记录压入时间戳
last_seg->seq_ = buffer_seq_;
buffer_seq_ ++;
//确定拷贝的块长度
copy_size = (data_size - copy_pos);
if(copy_size > MAX_SEGMENT_SIZE)
copy_size = MAX_SEGMENT_SIZE;
memcpy(last_seg->data_, pos, copy_size);
copy_pos += copy_size;
pos += copy_size;
last_seg->data_size_ = copy_size;
//压入发送队列
send_data_.push_back(last_seg);
}
//记录缓冲区的数据长度
buffer_data_size_ += copy_pos;
//尝试发送,立即发送
attempt_send(now_timer);
return copy_pos;
}
高性能服务框架revolver:RUDP(可靠UDP)算法详解
标签:
原文地址:http://www.cnblogs.com/blog-747674599/p/4255689.html