title: Implementing Bellman Ford Algorithm in Distance Vector Routing Protocol
body: <p>I cannot get the code to work for then the cost increases. I use the following functions in the code: </p>
  
  <ol>
  <li><p>UpdateRouteCost: This command takes two parameters, neighbor name and cost. For example, when user input the command UpdateRouteCost nodeB 4, your program should be able to update the corresponding link cost from this node to nodeB to 4.</p></li>
  <li><p>ReConstructRoutingTable: This is the function that should be used to execute BellmanFord algorithm and update the routing table based on UpdateRouteCost or receving an update from your neighbors.</p></li>
  <li><p>SendUpdate: This is the function that should be called whenever the node have updated your routing table.</p></li>
  <li><p>HandleMessage: This is the function that should be called whenever the node receives a message from your neighbors.</p></li>
  </ol>
  
  <p>To run the code you must open all 3 nodes by opening python3 node.py a.ini python3 node.py b.ini python3 node.py c.ini all simultaneously at once. Then you can update the cost and the routing table.</p>
  
  <p>node.py in python 3</p>
  
  <pre><code>    import socket
  import json
  import operator
  import sys
  import binascii
  import struct
  import threading
  import configparser
  
  
  def is_diff(obj1,obj2):
      if obj1 == None or obj2 == None:
          return False
      for k in obj1:
          if k == 'node':
              continue
          if obj1[k]['cost'] != obj2[k]['cost']:
              return True
      return False
  
  def print_table(obj):
      if obj == None:
          print("&gt;&gt;&gt;&gt;&gt;&gt; table is empty &lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;")
          return
      dest1 = obj['link1']['name']
      cost1 = obj['link1']['cost']
      next_hop1 = obj['link1']['name']
  
      dest2 = obj['link2']['name']
      cost2 = obj['link2']['cost']
      next_hop2 = obj['link2']['name']
  
      print('&gt;&gt;&gt;&gt; ' + obj['node']['name'] + ' routing table &lt;&lt;&lt;&lt;')
      print('-------------------------------------------------------')
      print('|   destination   |    link cost    |    next hop     |')
      print('|    %-13s|    %-13s|    %-13s|' % (dest1,cost1,next_hop1))
      print('|    %-13s|    %-13s|    %-13s|' % (dest2,cost2,next_hop2))
      print('-------------------------------------------------------')
  
  def print_diff(obj1,obj2):
      if obj1 == None or obj2 == None:
          return
      if is_diff(obj1,obj2):
          print("Before Update Table")
          print_table(obj1)
          print("After Update Table")
          print_table(obj2)
  
          for k in obj1:
              if k == "node":
                  continue
              if obj2[k]['cost'] != obj1[k]['cost']:
                  print("Node " + obj2[k]['name'] + " cost changed from " + str(obj1[k]['cost']) + " to " + str(obj2[k]['cost']))
      else:
          print("Node " + obj1['node']['name'] + " routing table not changed")
  
  def save_table(table):
      global node_configs
      node_configs[table['node']['name']] = table
  
  def listen_thread(port):
      s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
      s.bind(("0.0.0.0", port))
      while True:
          data, addr = s.recvfrom(1024)
          print(data)
  
  class RecvThread(threading.Thread):
      def __init__(self,port):
          super(RecvThread, self).__init__()
          self.port = port
  
      def run(self):
          global node_configs
          s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
          s.bind(("0.0.0.0", self.port))
          while True:
              data, addr = s.recvfrom(1024)
              print("Recv: ");
              dict = json.loads(str(data,encoding='utf-8'))
              print_table(dict)
              name = dict['node']['name']
              old = None
              if name in node_configs:
                  old = node_configs[name]
              save_table(dict)
              print_diff(old,dict)
              handle_message(dict)
              print("Input command(FirstLoad,FirstSend,Bye,MyRoutingTable,UpdateRouteCost):")
  
  class MyParser(configparser.ConfigParser):
      def as_dict(self):
          d = dict(self._sections)
          for k in d:
              d[k] = dict(d[k])
              d[k].pop('__name__', None)
          return d
  
  if len(sys.argv) != 2:
      print("Useage: python " + sys.argv[0] + " &lt;confg file&gt;")
      sys.exit(-1)
  
  def load_ini(file):
      cf = MyParser()
      cf.read(file)
      return cf.as_dict()
  
  config_dict = load_ini(sys.argv[1])
  listen_port = int(config_dict['node']['port'])
  #run recv thread
  t = RecvThread(int(listen_port))
  t.setDaemon(True)
  t.start()
  
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  
  node_configs = {}
  
  def reconstruct(obj):
      change = False
      name1 = config_dict['node']['name']
      name2 = obj['node']['name']
      for j in config_dict:
          if config_dict[j]['name'] == name2:
              link = j
              cost = int(config_dict[j]['cost'])
      for k in obj:
          link = obj[k]
          link_name = link['name']
          if k == "node":
              continue
          else:
              for i in config_dict:
                  test_node = config_dict[i]
                  test_name = test_node['name']
                  if i == "node":
                      continue
                  elif test_name == name2 and link_name == name1:
                      if test_node['cost'] != link['cost']:
                          test_node['cost'] = link['cost']
                          change = True
                  elif test_name == link_name:
                      a = int(test_node['cost'])
                      b = int(link['cost']) + cost
                      if a &gt; b:
                          test_node['cost'] = b
                          change = True
      if change:
          send()
  
  def handle_message(obj):
      reconstruct(obj)
  
  def send():
      global s
      #send to link1
      s.sendto(bytes(json.dumps(config_dict),'utf8'),(config_dict['link1']['ip'],int(config_dict['link1']['port'])))
      #send to link2
      s.sendto(bytes(json.dumps(config_dict),'utf8'),(config_dict['link2']['ip'],int(config_dict['link2']['port'])))
      print("Send config finished")
  
  
  def load(ini):
      config_dict = load_ini(ini)
      print("Load config file finished")
  
  def update_cost(node,cost):
      if not cost.isdigit():
          print("Cost is not number")
          return
      found = False
      for k in config_dict:
          if k == "node":
              continue
          v = config_dict[k]
          tmp_name = v['name']
          if tmp_name == node:
              v['cost'] = cost
              found = True
      if not found:
          print("Node &lt;" + node  + "&gt; not found in table")
      else:
          send()
  
  while True:
      print("Input command(FirstLoad,FirstSend,Bye,MyRoutingTable,UpdateRouteCost):")
      text = sys.stdin.readline().strip()
      if text == "FirstSend":
          send()
      elif text == "FirstLoad":
          load(sys.argv[1])
      elif text == "Bye":
          break
      elif text == "MyRoutingTable":
          print_table(config_dict)
      elif text.startswith("UpdateRouteCost"):
          cmds = text.split(" ")
          if len(cmds) != 3:
              print("Update command usage:UpdateRouteCost &lt;node name&gt; &lt;cost&gt;")
              continue
          name = cmds[1]
          cost = cmds[2]
          update_cost(name,cost)
      else:
          print("Invalid command")
  </code></pre>
  
  <p>a.ini </p>
  
  <pre><code>[node]
  name=nodeA
  port=1025
  
  [link1]
  name=nodeB
  ip=127.0.0.1
  port=1027
  cost=4
  
  [link2]
  name=nodeC
  ip=127.0.0.1
  port=1029
  cost=10
  </code></pre>
  
  <p>b.ini</p>
  
  <pre><code>[node]
  name=nodeB
  port=1027
  
  [link1]
  name=nodeA
  ip=127.0.0.1
  port=1025
  cost=4
  
  [link2]
  name=nodeC
  ip=127.0.0.1
  port=1029
  cost=1
  </code></pre>
  
  <p>c.ini</p>
  
  <pre><code>[node]
  name=nodeC
  port=1029
  
  [link1]
  name=nodeB
  ip=127.0.0.1
  port=1027
  cost=1
  
  [link2]
  name=nodeA
  ip=127.0.0.1
  port=1025
  cost=10
  </code></pre>