def send_data(settings, role): """ Send data to the other node """ # Setup kodo encoder_factory and encoder encoder_factory = kodo.FullVectorEncoderFactoryBinary( max_symbols=settings['symbols'], max_symbol_size=settings['symbol_size']) encoder = encoder_factory.build() data_in = os.urandom(encoder.block_size()) encoder.set_symbols(data_in) send_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) control_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) control_socket.settimeout(0.00000000000000000001) if role == 'client': address = (settings['server_ip'], settings['data_port']) send_settings(settings) control_socket.bind(('', settings['client_control_port'])) else: # server address = (settings['client_ip'], settings['data_port']) server_address = ( settings['server_ip'], settings['client_control_port']) control_socket.bind(('', settings['server_control_port'])) send(send_socket, "settings OK, sending", server_address) sent = 0 start = time.time() end = None while sent < settings['symbols'] * settings['max_redundancy'] / 100: packet = encoder.encode() send(send_socket, packet, address) sent += 1 try: control_socket.recv(1024) if end is None: end = time.time() break except socket.timeout: continue # if no ack was received we sent all packets if end is None: end = time.time() control_socket.close() size = encoder.block_size() * (float(sent) / settings['symbols']) seconds = end - start print("Sent {0} packets, {1} kB, in {2}s, at {3:.2f} kb/s.".format( sent, size / 1000, seconds, 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 kodoencoder(data): # Set the number of symbols (i.e. the generation size in RLNC # terminology) and the size of a symbol in bytes dataSize = len(data) print 'block data size: ', dataSize symbols = dataSize / SYMBOLSIZE if dataSize % SYMBOLSIZE: symbols = symbols + 1 # In the following we will make an encoder factory. # The factories are used to build actual encoder encoder_factory = kodo.FullVectorEncoderFactoryBinary( max_symbols=symbols, max_symbol_size=SYMBOLSIZE) encoder = encoder_factory.build() # Assign the data buffer to the encoder so that we can # produce encoded symbols encoder.set_const_symbols(data) return encoder, symbols
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 handle(self): # overwrite the 'handle' method print 'Connected from', self.client_address while True: ReData = self.request.recv(40960) if not ReData: print('No Request') break else: action, filename = ReData.split( ) # receive the client's request and get the file name self.request.sendall('Request accepted') time.sleep(1) ############################### Encode part # Set the number of symbols(the generation size in RLNC terminology # Set the size of a symbol in bytes symbols = 20 symbol_size = 1000 # In the following we will make an encoder factory. #The factories are used to build actual encoder encoder_factory = kodo.FullVectorEncoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) encoder = encoder_factory.build() # get the data to encode f = open(filename, 'rb') #start = time.time() data = f.read() if not data: print('No valid data') f.close() # Assign the data buffer to the encoder so that we can # produce encoded symbols encoder.set_symbols(data) #self.request.send(data) print('Encoding and starting send file...') packet_number = 1 start = time.time() while True: FiSign = self.request.recv(40960) print FiSign if FiSign == 'Decode finished': break else: packet = encoder.write_payload( ) # Generate an encoded packet print('packet{} encoded'.format(packet_number)) #print packet self.request.send(packet) packet_number += 1 #if not self.request.recv(40960) : #if FiSign =='Decode finished' : # break time.sleep(1) self.request.sendall('EOF') print('Send coded data successfully!') finish = time.time() break self.request.close() DeliverTime = finish - start print 'Disconnected from', self.client_address FileSize = os.path.getsize(filename) print('File size :', FileSize) print('Deliver time :', DeliverTime) print('Average Thoughput: {} MB/s'.format(FileSize / (DeliverTime * 1000000)))
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(): """ 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)
result = {'encoder': encoder, 'field_size': field_size} result['symbol_len'] = kodo_object.symbol_size() result['gen_size'] = kodo_object.symbols() return result 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)
def main(): """Example of a sender which encodes and sends a file.""" parser = argparse.ArgumentParser(description=main.__doc__) parser.add_argument( '--file-path', type=str, help='Path to the file which should be send.', default=os.path.realpath(__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() # Check file. if not os.path.isfile(args.file_path): print("{} is not a valid file.".format(args.file_path)) sys.exit(1) # 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 encoder factory. # The factories are used to build actual encoder encoder_factory = kodo.FullVectorEncoderFactoryBinary( max_symbols=symbols, max_symbol_size=symbol_size) encoder = encoder_factory.build() sock = socket.socket( family=socket.AF_INET, type=socket.SOCK_DGRAM, proto=socket.IPPROTO_UDP) sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2) # Get the data to encode. f = open(os.path.expanduser(args.file_path), 'rb') data_in = f.read() f.close() # Assign the data buffer to the encoder so that we can # produce encoded symbols encoder.set_symbols(data_in) address = (args.ip, args.port) print("Processing") while True and not args.dry_run: time.sleep(0.2) # Generate an encoded packet packet = encoder.encode() print("Packet encoded!") # Send the packet. sock.sendto(packet, address) print("Processing finished")
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)