Files
CPP_Core/Core/transmit_protocol/kcp深度结合fec.txt
T
2026-06-16 10:56:40 +08:00

183 lines
6.2 KiB
Plaintext

根据kcp pcb的状态参数 以及包大小 确认 s s为16的跃迁 每一包都要确定fec
fec发送队列接收队列是二层链表
丢包的时候根据各种参数 来重传fec里的包
比如单包80 32 + 32 + 32 s=32 n=3 根据丢包率10% k=1 丢包率 50% k=4
kcp包头添加 fec的12包头,发送端,接收端,缓存链表改成二层结构。
需要在快速重传 重传的位置添加位置
写入步骤
#ifndef FEC_USE_Packet
void send_fec_encode_data(char* data, UDP_FEC_CB* cb, void* user) {
UDP_FEC_Packet_Header header;
header.group_id = cb->send_group_id;
IUINT32 header_len = sizeof(UDP_FEC_Packet_Header);
fec_encode((fecPayload*)(data), cb->enc, cb->s);
ND* t = cb->send_data_list->head;
while (t) {
size_t send_size = header_len + t->size;
char* send_data = (char*)g_malloc(send_size);
memcpy(send_data, &header, header_len);
memcpy(send_data + header_len, t->data, t->size);
// printf("send group id %u \n", header.group_id);
cb->next_send((Base_CB*)cb, send_data, send_size, user);
g_free(send_data);
t = t->next;
}
clear_all_node(cb->send_data_list);
}
void handle_send_piece(char* data, void* user){
Piece_Manager_User* pmu = (Piece_Manager_User*)user;
UDP_FEC_CB* cb = pmu->cb;
if (cb->enc == NULL) {
refresh_Encoder(cb, cb->s, cb->n, cb->k);
}
send_fec_encode_data(data, cb, pmu->user);
cb->send_times++;
if (cb->send_times == cb->enc->e.n) {
cb->send_times = 0;
cb->send_group_id++;
refresh_Encoder(cb, cb->s, cb->n, cb->k);
}
}
void recv_all_origin_packet(UDP_FEC_CB* cb, void* user) {
ND* t = cb->decode_origin_list->head;
while (t) {
cb->next_recv((Base_CB*)cb, t->data + fec_header_len, t->size - fec_header_len, user);
t = t->next;
}
}
void flush_recv_decode(UDP_FEC_CB* cb, void* user) {
if (cb->decode_origin_list_size == cb->n && cb->last_cache_i == cb->n - 1) {
if (recv_debug) {
printf("【%d】收到全部帧 原始帧数%d 恢复帧数%d \n", cb->recv_group_id, cb->decode_origin_list_size, cb->decode_cache_list_size);
}
recv_all_origin_packet(cb, user);
}
else { // 需要恢复
if (cb->decode_origin_list_size + cb->decode_cache_list_size >= cb->n) { // 具备恢复条件
{
// fec 解码成功 开始恢复
ND* t = cb->decode_origin_list->head;
while (t) {
fec_decode(t->data, t->size, 1, cb->dec);
t = t->next;
}
t = cb->decode_cache_list->head;
while (t) {
fec_decode(t->data, t->size, 1, cb->dec);
t = t->next;
}
flush_fec_decoder(cb->dec);
}
if (recv_debug) {
print_dec_state(cb);
}
if (cb->dec->lostPackets == 0) {
// 恢复成功
if (recv_debug) {
printf("【%d】恢复成功 原始帧数%d 恢复帧数%d \n", cb->recv_group_id, cb->decode_origin_list_size, cb->decode_cache_list_size);
}
ND* t = cb->recv_data_list->head;
while (t) {
// 解码后的数据 无偏移
cb->next_recv((Base_CB*)cb, t->data, t->size, user);
t = t->next;
}
clear_all_node(cb->recv_data_list);
} else {
// 恢复失败
if (recv_debug) {
printf("【%d】恢复失败 原始帧数%d 恢复帧数%d \n", cb->recv_group_id, cb->decode_origin_list_size, cb->decode_cache_list_size);
}
recv_all_origin_packet(cb, user);
}
} else {
if (recv_debug) {
printf("【%d】不具备恢复条件 原始帧数%d 恢复帧数%d \n", cb->recv_group_id, cb->decode_origin_list_size, cb->decode_cache_list_size);
}
recv_all_origin_packet(cb, user);
}
}
// 解码完成清理状态
clear_all_node(cb->decode_origin_list);
clear_all_node(cb->decode_cache_list);
cb->decode_origin_list_size = 0;
cb->decode_cache_list_size = 0;
delete_fec_decoder(cb->dec);
cb->dec = new_fec_decoder(cb, decode_writer);
cb->last_cache_i = 0;
}
#endif
UDP_FEC_CB* cb = (UDP_FEC_CB*)bcb;
// Piece_Manager_User pmu;
// pmu.cb = cb;
// pmu.user = user;
// IUINT16 s, n, k, last_s;
// calc_snk(total_len, cb->redundancy, &s, &n, &k, &last_s);
// int w = 8;
// int g = 4;
// int b = 0;
// char *errmsg = NULL;
// fec_encoder* enc = new_fec_encoder(cb, encode_writer, &errmsg, s, n, k, w, g, b);
//
// char* data = g_malloc(s);
// for (IUINT16 i = 0; i < n; i++) {
// Buf_Type buf = total_buf + i * s;
// if (i != n - 1) {
// fec_encode((fecPayload*)buf, enc);
// } else {
// memmove(data, buf, last_s);
// fec_encode((fecPayload*)data, enc);
// }
// }
// g_free(data);
//
//
// UDP_FEC_Packet_Header header;
// header.group_id = cb->send_group_id;
// header.total_len = total_len;
// header.type = UDP_FEC_CB_Packet;
//
//
// ND* t = cb->send_data_list->head;
// size_t send_size = fec_packet_header_len + t->size;
// char* send_data = g_malloc(send_size);
// while (t) {
// memcpy(send_data, &header, fec_packet_header_len);
// memcpy(send_data + fec_packet_header_len, t->data, t->size);
// //Fec_Header* h = (Fec_Header*)send_data;
// // h->n;
// // IUINT16 k = (h->kwg) & ((1 << KBITS) - 1);
// // IUINT16 w = ( (h->kwg) >> KBITS) & ((1 << WBITS) - 1);
// // IUINT16 g = (h->kwg) >> (KBITS + WBITS);
// // send_data += t->size;
// cb->next_send((Base_CB*)cb, send_data, send_size, user);
// t = t->next;
// }
// // cb->next_send((Base_CB*)cb, total, size, user);
// clear_all_node(cb->send_data_list);
// g_free(send_data);
// delete_fec_encoder(enc);
//
//
//
// cb->send_group_id++;