Hello everyone, very sorry to have bothered you, recently I would like to use KODO library to practice network coding implementation, but I don't familiar with C/C++ (I more familiar with JAVA), so I just write simple code to send/receive coded packets via socket, here is my code:
Server.cpp (Sender)
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <kodo/file_encoder.hpp>
#include <kodo/object_decoder.hpp>
#include <kodo/rlnc/full_rlnc_codes.hpp>
#include <kodo/set_systematic_off.hpp>
/// Often we want to encode / decode data that exceed a single
/// encoding/decoding block. In this case we need to "chop" up
/// the data into manageable chunks and then encode and decode
/// each chuck separately. This examples shows how to use the
/// file encoder in Kodo. The file encoder operates directly on
/// a file in the file-system. For decoding we use an object decoder
/// which decodes data to memory, but which is compatible with
/// file encoder.
int main(){
//Initial Server Socket
int listenfd = 0,connfd = 0;
struct sockaddr_in serv_addr;
listenfd = socket(AF_INET, SOCK_STREAM, 0);
printf("[socket retrieve success]\n");
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
bind(listenfd, (struct sockaddr*)&serv_addr,sizeof(serv_addr));
if(listen(listenfd, 10) == -1){
printf("Failed to listen\n");
return -1;
}
// Set the number of symbols (i.e. the generation size in RLNC terminology) and the size of a symbol in bytes
uint32_t max_symbols = 42;
uint32_t max_symbol_size = 64;
std::string encode_filename = "encodeFile.bin";
// Create a test file for encoding.
std::ofstream encode_file;
encode_file.open (encode_filename, std::ios::binary);
uint32_t file_size = 500000;
std::vector<char> encode_data(file_size);
std::vector<char> decode_data;
// Just write some bytes to the file
for(uint32_t i = 0; i < file_size; ++i){
encode_data[i] = rand() % 255;
}
encode_file.write(&encode_data[0], file_size);
encode_file.close();
// Select the encoding and decoding algorithms
typedef kodo::full_rlnc_encoder<fifi::binary> encoder_t;
typedef kodo::full_rlnc_decoder<fifi::binary> decoder_t;
// Now for the encoder we use a file_encoder with the chosen encoding algorithm
typedef kodo::file_encoder<encoder_t> file_encoder_t;
// For decoding we use an object_decoder with the chosen decoding algorithm
typedef kodo::object_decoder<decoder_t> object_decoder_t;
// Create the encoder factory - builds the individual encoders used
file_encoder_t::factory encoder_factory(max_symbols, max_symbol_size);
// Create the actual file encoder using the encoder factory and the filename of the file to be encoded
file_encoder_t file_encoder(encoder_factory, encode_filename);
// Create the decoder factory - build the individual decoders used
object_decoder_t::factory decoder_factory(max_symbols, max_symbol_size);
// Create the object decoder using the decoder factory and the size of the file to be decoded
object_decoder_t object_decoder(decoder_factory, file_size);
// Now in the following loop we go through all the encoders
// needed to encode the entire file. We the build the corresponding
// decoder and decode the chunk immediately. In practice where
// encoders and decoders are on different devices e.g. connected
// over a network, we would have to pass also the encoder and decoder
// index between the source and sink to allow the correct data would
// passed from encoder to corresponding decoder.
//Send encode data via socket
while(1){
connfd = accept(listenfd, (struct sockaddr*)NULL ,NULL); // accept awaiting request
printf("[Start encode file]......\n");
for(uint32_t i = 0; i < file_encoder.encoders(); ++i){
auto encoder = file_encoder.build(i);
auto decoder = object_decoder.build(i);
// Set the encoder non-systematic
if(kodo::has_systematic_encoder<encoder_t>::value)
kodo::set_systematic_off(encoder);
std::vector<uint8_t> payload(encoder->payload_size());
while( !decoder->is_complete() ){
// Encode a packet into the payload buffer
encoder->encode( &payload[0] );
// In practice send the payload over a network, save it to
// a file etc. Then when needed build and pass it to the decoder
send(connfd,&payload[0],payload.size(),0);
// Pass that packet to the decoder
decoder->decode( &payload[0] );
}
}
printf("[File encode already]\n");
close(connfd);
sleep(1);
}
return 0;
}
Client.cpp (Receiver)
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <kodo/file_encoder.hpp>
#include <kodo/object_decoder.hpp>
#include <kodo/rlnc/full_rlnc_codes.hpp>
#include <kodo/set_systematic_off.hpp>
int main(){
//Initial Client Socket
int sockfd = 0,n = 0;
struct sockaddr_in serv_addr;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0))< 0){
printf("\n Error : Could not create socket \n");
return 1;
}
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(5000);
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))<0){
printf("\n Error : Connect Failed \n");
return 1;
}
// Set the number of symbols (i.e. the generation size in RLNC terminology) and the size of a symbol in bytes
uint32_t max_symbols = 42;
uint32_t max_symbol_size = 64;
uint32_t file_size = 500000;
std::vector<char> decode_data;
typedef kodo::full_rlnc_decoder<fifi::binary> decoder_t;
// For decoding we use an object_decoder with the chosen decoding algorithm
typedef kodo::object_decoder<decoder_t> object_decoder_t;
// Create the decoder factory - build the individual decoders used
object_decoder_t::factory decoder_factory(max_symbols, max_symbol_size);
// Create the object decoder using the decoder factory and the size of the file to be decoded
object_decoder_t object_decoder(decoder_factory, file_size);
// Receive data and encode
std::vector<uint8_t> payload;
payload.resize(100);
n = recv(sockfd,&payload[0],payload.size(),0);
printf("[Receive encode file]......\n");
while(n > 0){
auto decoder = object_decoder.build(n);//what's the parameter in build( )????
payload.resize(n);
recv(sockfd,&payload[0],payload.size(),0);
// Pass that packet to the decoder
decoder->decode( &payload[0] );
std::vector<uint8_t> data_out(decoder->block_size());
decoder->copy_symbols(sak::storage(data_out));
data_out.resize(decoder->bytes_used());
decode_data.insert(decode_data.end(),
data_out.begin(),
data_out.end());
}
printf("[File decode already]\n");
if( n < 0){
printf("\n Read Error \n");
}
return 0;
}
After executing Server.cpp/Client.cpp, I have some problems, "Client(Receiver)" cannot decode coded packet after receiving, here is message in server/client console:
Server:
[socket retrieve success]
[Start encode file]......
[File encode already]
Client:
[Receive encode file]......
Assertion failed: (symbol_index < SuperCoder::symbols()), function decode_symbol, file /Users/macbook/Documents/Network_Coding/kodo/src/kodo/bidirectional_linear_block_decoder.hpp, line 118.
Abort trap: 6
I search google and try to revise my code, but it doesn't work, would you mind give me some hints to let me finish my practice?
I'm really so sorry to trouble you, I would greatly appreciate it if you kindly give me some help.