def receive_data(settings, role): """Receive data from the other node.""" # Setup kodo encoder_factory and decoder decoder_factory = kodo.FullVectorDecoderFactoryBinary( max_symbols=settings['symbols'], max_symbol_size=settings['symbol_size']) decoder = decoder_factory.build() send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Set receiving sockets data_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) data_socket.settimeout(settings['timeout']) data_socket.bind(('', settings['data_port'])) if role == 'client': address = (settings['server_ip'], settings['server_control_port']) send_settings(settings) else: # server address = (settings['client_ip'], settings['client_control_port']) send(send_socket, "settings OK, receiving", address) # Decode coded packets received = 0 start = time.time() end = None while 1: try: packet = data_socket.recv(settings['symbol_size'] + 100) if not decoder.is_complete(): decoder.read_payload(packet) received += 1 if decoder.is_complete(): if end is None: end = time.time() # stopping time once send(send_socket, "Stop sending", address) except socket.timeout: break # no more data arriving # in case we did not complete if end is None: end = time.time() data_socket.close() if not decoder.is_complete(): print("Decoding failed") size = decoder.block_size() * (float(received) / settings['symbols']) seconds = end - start print("Received {0} packets, {1}kB, in {2}s, at {3:.2f} kb/s.".format( received, size / 1000, seconds, decoder.block_size() * 8 / 1000 / seconds ))
def main(): """Simple example showing how to encode and decode a block of memory.""" # Set the number of symbols (i.e. the generation size in RLNC # terminology) and the size of a symbol in bytes symbols = 8 symbol_size = 160 # In the following we will make an encoder/decoder factory. # The factories are used to build actual encoders/decoders encoder_factory = kodo.FullVectorEncoderFactoryBinary(symbols, symbol_size) encoder = encoder_factory.build() decoder_factory = kodo.FullVectorDecoderFactoryBinary(symbols, symbol_size) decoder = decoder_factory.build() # Create some data to encode. In this case we make a buffer # with the same size as the encoder's block size (the max. # amount a single encoder can encode) # Just for fun - fill the input data with random data data_in = os.urandom(encoder.block_size()) # Assign the data buffer to the encoder so that we can # produce encoded symbols encoder.set_const_symbols(data_in) print("Processing") packet_number = 0 encoder.set_systematic_off() while not decoder.is_complete(): # Generate an encoded packet packet = encoder.write_payload() print("Packet {} encoded!".format(packet_number)) # Pass that packet to the decoder decoder.read_payload(packet) print("Packet {} decoded!".format(packet_number)) packet_number += 1 print("rank: {}/{}".format(decoder.rank(), decoder.symbols())) print("Processing finished") # The decoder is complete, now copy the symbols from the decoder data_out = decoder.copy_from_symbols() # Check if we properly decoded the data print("Checking results") if data_out == data_in: print("Data decoded correctly") else: print("Unable to decode please file a bug report :)") sys.exit(1)
def kododecoder(blockSize): # Set the number of symbols (i.e. the generation size in RLNC # terminology) and the size of a symbol in bytes #file_size = os.path.getsize(FILE_ORIGINAL_PATH) print 'kodo block Size: ', blockSize symbols = blockSize / SYMBOLSIZE if blockSize % SYMBOLSIZE: symbols = symbols + 1 #print 'symbolsize,symbols: ',SYMBOLSIZE, symbols # In the following we will make an decoder factory. # The factories are used to build actual decoder decoder_factory = kodo.FullVectorDecoderFactoryBinary( max_symbols=symbols, max_symbol_size=SYMBOLSIZE) decoder = decoder_factory.build() print 'symbolsize, symbols ', SYMBOLSIZE, symbols return decoder
def main(): """ Switch systematic off example. This example shows how to enable or disable systematic coding for coding stacks that support it. Systematic coding is used to reduce the amount of work done by an encoder and a decoder. This is achieved by initially sending all symbols which has not previously been sent uncoded. Kodo allows this feature to be optionally turn of or off. """ # Set the number of symbols (i.e. the generation size in RLNC # terminology) and the size of a symbol in bytes symbols = 16 symbol_size = 160 # In the following we will make an encoder/decoder factory. # The factories are used to build actual encoders/decoders encoder_factory = kodo.FullVectorEncoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) encoder = encoder_factory.build() decoder_factory = kodo.FullVectorDecoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) decoder = decoder_factory.build() # Create some data to encode. In this case we make a buffer # with the same size as the encoder's block size (the max. # amount a single encoder can encode) # Just for fun - fill the input data with random data data_in = os.urandom(encoder.block_size()) # Assign the data buffer to the encoder so that we may start # to produce encoded symbols from it encoder.set_symbols(data_in) print("Starting encoding / decoding") while not decoder.is_complete(): # If the chosen codec stack supports systematic coding if 'is_systematic_on' in dir(encoder): # With 50% probability toggle systematic if random.choice([True, False]): if encoder.is_systematic_on(): print("Turning systematic OFF") encoder.set_systematic_off() else: print("Turning systematic ON") encoder.set_systematic_on() # Encode a packet into the payload buffer packet = encoder.encode() if random.choice([True, False]): print("Drop packet") continue # Pass that packet to the decoder decoder.decode(packet) print("Rank of decoder {}".format(decoder.rank())) # Symbols that were received in the systematic phase correspond # to the original source symbols and are therefore marked as # decoded print("Symbols decoded {}".format(decoder.symbols_uncoded())) # The decoder is complete, now copy the symbols from the decoder data_out = decoder.copy_symbols() # Check we properly decoded the data if data_out == data_in: print("Data decoded correctly") else: print("Unexpected failure to decode please file a bug report :)") sys.exit(1)
def main(): """ Encode recode decode example. In Network Coding applications one of the key features is the ability of intermediate nodes in the network to recode packets as they traverse them. In Kodo it is possible to recode packets in decoders which provide the recode() function. This example shows how to use one encoder and two decoders to simulate a simple relay network as shown below (for simplicity we have error free links, i.e. no data packets are lost when being sent from encoder to decoder1 and decoder1 to decoder2): +-----------+ +-----------+ +-----------+ | encoder |+---.| decoder1 |+---.| decoder2 | +-----------+ | (recoder) | +-----------+ +-----------+ In a practical application recoding can be using in several different ways and one must consider several different factors e.g. such as reducing linear dependency by coordinating several recoding nodes in the network. Suggestions for dealing with such issues can be found in current research literature (e.g. MORE: A Network Coding Approach to Opportunistic Routing). ********************************************************************* NOTE: This is for the forwarding/recoding example discussed in class In the first case H is a recoder and in the second a forwarder! S -> R has erasure rate e1 = 80% S -> H has erasure rate e2 = 10% H -> R has erasure rate e3 = 10% The network is like this: ---- H ---- / \ / \ S --------------R Can change the encoder and decoder factories to Binary8 if want to compare with a larger field but it's much slower so if you don't want to wait reduce the num_runs. DOUBLE CHECK THE RESULTS WITH THEORY! ********************************************************************* """ # Set the number of symbols (i.e. the generation size in RLNC # terminology) and the size of a symbol in bytes symbols = 100 #42 symbol_size = 140 #160 num_runs = 1000 # Erasure rates e1 = 0.8 e2 = 0.1 e3 = 0.1 # Encoder factory used to build encoder encoder_factory = kodo.FullVectorEncoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) encoder = encoder_factory.build() encoder.set_systematic_off() # H Recoder case # Total packets sent by the source and total number of redundant packets total_packets = 0 total_red_packets = 0 for i in range(num_runs): # Decoder factory used to build recoder and decoder decoder_factory = kodo.FullVectorDecoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) decoder1 = decoder_factory.build() decoder2 = decoder_factory.build() # Create some data to encode. In this case we make a buffer # with the same size as the encoder's block size (the max. # amount a single encoder can encode) # Just for fun - fill the input data with random data data_in = os.urandom(encoder.block_size()) # Assign the data buffer to the encoder so that we may start # to produce encoded symbols from it encoder.set_const_symbols(data_in) # Packets sent by source and redundant packets for this run packets_needed = 0 red_packets = 0 past_rank = 0 while not decoder2.is_complete(): # Encode a packet into the payload buffer from the source packet = encoder.write_payload() packets_needed += 1 # S -> R direct path if random.uniform(0.0, 1.0) > e1: past_rank = decoder2.rank() decoder2.read_payload(packet) if decoder2.rank() == past_rank: red_packets += 1 # The multihop path # S -> H where H is a recoder if random.uniform(0.0, 1.0) > e2: decoder1.read_payload(packet) # H -> R # Not nested in S -> H because sending is independent of receiving in recoder case. # i.e. it always sends something out with the info it has already. # First produce a new recoded packet from the current # decoding buffer, and place it into the payload buffer packet = decoder1.write_payload() if random.uniform(0.0, 1.0) > e3: past_rank = decoder2.rank() decoder2.read_payload(packet) if decoder2.rank() == past_rank: red_packets += 1 # decoder2 should now be complete, # copy the symbols from the decoder data_out2 = decoder2.copy_from_symbols() # Check we properly decoded the data if data_out2 == data_in: total_packets += packets_needed total_red_packets += red_packets else: print("Unexpected failure to decode please file a bug report :)") sys.exit(1) print("Recoder:") print("Avg. packets needed:") print(total_packets / float(num_runs)) print("Avg. Redundant packets:") print(total_red_packets / float(num_runs)) print('') ######################################################################## # H Forwarder case # Total packets sent by the source and total number of redundant packets total_packets = 0 total_red_packets = 0 for i in range(num_runs): # Decoder factory used to build recoder and decoder decoder_factory = kodo.FullVectorDecoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) decoder1 = decoder_factory.build() decoder2 = decoder_factory.build() # Create some data to encode. In this case we make a buffer # with the same size as the encoder's block size (the max. # amount a single encoder can encode) # Just for fun - fill the input data with random data data_in = os.urandom(encoder.block_size()) # Assign the data buffer to the encoder so that we may start # to produce encoded symbols from it encoder.set_const_symbols(data_in) # Packets sent by source and redundant packets for this run packets_needed = 0 red_packets = 0 past_rank = 0 while not decoder2.is_complete(): # Encode a packet into the payload buffer from the source packet = encoder.write_payload() packets_needed += 1 # S -> R direct path if random.uniform(0.0, 1.0) > e1: past_rank = decoder2.rank() decoder2.read_payload(packet) if decoder2.rank() == past_rank: red_packets += 1 # The multihop path # S -> H where H is a recoder if random.uniform(0.0, 1.0) > e2: decoder1.read_payload(packet) # H -> R # Only get to this point if S -> H succeeds # It's going to be the same packet from the encoder since # just forwarding here! if random.uniform(0.0, 1.0) > e3: past_rank = decoder2.rank() decoder2.read_payload(packet) if decoder2.rank() == past_rank: red_packets += 1 # decoder2 should now be complete, # copy the symbols from the decoder data_out2 = decoder2.copy_from_symbols() # Check we properly decoded the data if data_out2 == data_in: total_packets += packets_needed total_red_packets += red_packets else: print("Unexpected failure to decode please file a bug report :)") sys.exit(1) print("H Forwarder:") print("Avg. packets needed:") print(total_packets / float(num_runs)) print("Avg. Redundant packets:") print(total_red_packets / float(num_runs))
def main(): """ Multicast example, reciever part. An example where data is received, decoded, and finally written to a file. """ parser = argparse.ArgumentParser(description=main.__doc__) parser.add_argument('--output-file', type=str, help='Path to the file which should be received.', default='output_file') parser.add_argument('--ip', type=str, help='The ip to send to.', default=MCAST_GRP) parser.add_argument('--port', type=int, help='The port to send to.', default=MCAST_PORT) parser.add_argument('--dry-run', action='store_true', help='Run without network use.') args = parser.parse_args() # Set the number of symbols (i.e. the generation size in RLNC # terminology) and the size of a symbol in bytes symbols = 64 symbol_size = 1400 # In the following we will make an decoder factory. # The factories are used to build actual decoder decoder_factory = kodo.FullVectorDecoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) decoder = decoder_factory.build() sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM, proto=socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('', args.port)) mreq = struct.pack("4sl", socket.inet_aton(args.ip), socket.INADDR_ANY) sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) if args.dry_run: sys.exit(0) print("Processing...") while not decoder.is_complete(): time.sleep(0.2) packet = sock.recv(10240) decoder.read_payload(packet) print("Packet received!") print("Decoder rank: {}/{}".format(decoder.rank(), decoder.symbols())) # Write the decoded data to the output file f = open(args.output_file, 'wb') f.write(decoder.copy_from_symbols()) f.close() print("Processing finished.")
def main(): """ Encode recode decode example. In Network Coding applications one of the key features is the ability of intermediate nodes in the network to recode packets as they traverse them. In Kodo it is possible to recode packets in decoders which provide the recode() function. This example shows how to use one encoder and two decoders to simulate a simple relay network as shown below (for simplicity we have error free links, i.e. no data packets are lost when being sent from encoder to decoder1 and decoder1 to decoder2): +-----------+ +-----------+ +-----------+ | encoder |+---.| decoder1 |+---.| decoder2 | +-----------+ | (recoder) | +-----------+ +-----------+ In a practical application recoding can be using in several different ways and one must consider several different factors e.g. such as reducing linear dependency by coordinating several recoding nodes in the network. Suggestions for dealing with such issues can be found in current research literature (e.g. MORE: A Network Coding Approach to Opportunistic Routing). """ # Set the number of symbols (i.e. the generation size in RLNC # terminology) and the size of a symbol in bytes symbols = 42 symbol_size = 160 # In the following we will make an encoder/decoder factory. # The factories are used to build actual encoders/decoders encoder_factory = kodo.FullVectorEncoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) encoder = encoder_factory.build() decoder_factory = kodo.FullVectorDecoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) decoder1 = decoder_factory.build() decoder2 = decoder_factory.build() # Create some data to encode. In this case we make a buffer # with the same size as the encoder's block size (the max. # amount a single encoder can encode) # Just for fun - fill the input data with random data data_in = os.urandom(encoder.block_size()) # Assign the data buffer to the encoder so that we may start # to produce encoded symbols from it encoder.set_const_symbols(data_in) while not decoder2.is_complete(): # Encode a packet into the payload buffer packet = encoder.write_payload() # Pass that packet to decoder1 decoder1.read_payload(packet) # Now produce a new recoded packet from the current # decoding buffer, and place it into the payload buffer packet = decoder1.write_payload() # Pass the recoded packet to decoder2 decoder2.read_payload(packet) # Both decoder1 and decoder2 should now be complete, # copy the symbols from the decoders data_out1 = decoder1.copy_from_symbols() data_out2 = decoder2.copy_from_symbols() # Check we properly decoded the data if data_out1 == data_in and data_out2 == data_in: print("Data decoded correctly") else: print("Unexpected failure to decode please file a bug report :)") sys.exit(1)
if __name__ == "__main__": if len(sys.argv) > 2: encoder_decoder = sys.argv[1] SYMBOL_SIZE = int(sys.argv[2]) if coding_mode == "encode": if encoder_decoder == "FullVector": fw_fac = kodo.FullVectorEncoderFactoryBinary(GEN_SIZE, SYMBOL_SIZE) elif encoder_decoder == "SlidingWindow": fw_fac = kodo.SlidingWindowEncoderFactoryBinary( GEN_SIZE, SYMBOL_SIZE) redundancy = 10 elif coding_mode in ("decode", "recode"): if encoder_decoder == "FullVector": fw_fac = kodo.FullVectorDecoderFactoryBinary(GEN_SIZE, SYMBOL_SIZE) elif encoder_decoder == "SlidingWindow": fw_fac = kodo.SlidingWindowDecoderFactoryBinary( GEN_SIZE, SYMBOL_SIZE) else: fw_fac = None encoder_info = convert_encoder(fw_fac) JSONL_FILE_PATH = "pd_{}_{}_{}.jsonl".format(encoder_decoder, SYMBOL_SIZE, GEN_SIZE) # Bind sockets and start forwards and backwards processes recv_sock, send_sock = bind_raw_sock_pair(ingress_iface, egress_iface) fw_proc = multiprocessing.Process(target=forwards_forward, args=(recv_sock, send_sock, fw_fac))
if action == 'get' : if confirm(sock, client_command) : print ('Server accepted request') print('Receive packet and decode...') #f = open(filename , 'wb') times=0 while True : # Set the number of symbols (i.e. the generation size in RLNC # terminology) and the size of a symbol in bytes symbols = 110 symbol_size = 10000 # In the following we will make an decoder factory. # The factories are used to build actual decoder decoder_factory = kodo.FullVectorDecoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) decoder = decoder_factory.build() #time.sleep(1) #count=0 while not decoder.is_complete() : #count+=1 #print(count) sock.sendall('Decode not finished') packet = sock.recv(40960000) decoder.read_payload(packet) #decoding packet print('packet{}/{}decoded'.format(decoder.rank(),decoder.symbols())) f = open(filename ,'a') f.write(decoder.copy_symbols()) # store the decoded data
def main(): """Example showing the result of enabling the symbol status updater.""" # Set the number of symbols (i.e. the generation size in RLNC # terminology) and the size of a symbol in bytes symbols = 50 symbol_size = 160 # In the following we will make an encoder/decoder factory. # The factories are used to build actual encoders/decoders # To show the effect of the symbol status updater we need to use a lower # sized field - the lower the better. encoder_factory = kodo.FullVectorEncoderFactoryBinary(symbols, symbol_size) encoder = encoder_factory.build() decoder_factory = kodo.FullVectorDecoderFactoryBinary(symbols, symbol_size) # Create two decoders, one which has the status updater turned on, and one # which has it off. decoder1 = decoder_factory.build() decoder2 = decoder_factory.build() decoder2.set_status_updater_on() print("decoder 1 status updater: {}".format( decoder1.is_status_updater_enabled())) print("decoder 2 status updater: {}".format( decoder2.is_status_updater_enabled())) # Create some data to encode. In this case we make a buffer # with the same size as the encoder's block size (the max. # amount a single encoder can encode) # Just for fun - fill the input data with random data data_in = os.urandom(encoder.block_size()) # Assign the data buffer to the encoder so that we can # produce encoded symbols encoder.set_const_symbols(data_in) # Skip the systematic phase as the effect of the symbol status decoder is # only visible when reading coded packets. encoder.set_systematic_off() print("Processing") while not decoder1.is_complete(): # Generate an encoded packet payload = encoder.write_payload() payload_copy = copy.copy(payload) # Pass that packet to the decoder decoder1.read_payload(payload) decoder2.read_payload(payload_copy) print("decoder 1: {}".format(decoder1.symbols_uncoded())) print("decoder 2: {}".format(decoder2.symbols_uncoded())) print("-----------------") print("Processing finished") # The decoder is complete, now copy the symbols from the decoder data_out1 = decoder1.copy_from_symbols() data_out2 = decoder2.copy_from_symbols() # Check if we properly decoded the data print("Checking results") if data_out1 == data_in and data_out2 == data_in: print("Data decoded correctly") else: print("Unable to decode please file a bug report :)") sys.exit(1)