Connection force closed by Remote host - Python UDP programming

658 Views Asked by At

I have a code here for link state routing protocol that I am trying to run, but for some stupid reason it gives me an error saying the remote host shutdown the connection. My code takes three arguments, namely the router ID, the port and the config file containing neighboring router nodes and their costs and port nos.

The connection protocol I use is UDP, not TCP.. The biggest problem that i seem to have is that the code still somehow keeps producing the output (last three lines in screenshot).

Here is my screenshot of output:

Screenshot of output

and my code:

    #!/usr/bin/python

import socket
import pickle
import sys
import random
from threading import Thread,Lock
import time
from collections import defaultdict


class Graph:
  def __init__(self):
    self.lock = Lock()
    self.nodes = set()
    self.edges = defaultdict(list)
    self.distances = {}

  def add_node(self, value):
    self.lock.acquire()
    try:
      self.nodes.add(value)
    finally:
      self.lock.release()

  def add_edge(self, from_node, to_node, distance):
    self.lock.acquire()
    try:
      self.edges[from_node].append(to_node)
      self.edges[to_node].append(from_node)
      self.distances[(from_node, to_node)] = distance
      self.distances[(to_node, from_node)] = distance
    finally:
      self.lock.release()


def dijkstra(graph, initial):
  visited = {initial: 0}
  path = {}

  nodes = set(graph.nodes)

  while nodes:
    min_node = None
    for node in nodes:
      if node in visited:
        if min_node is None:
          min_node = node
        elif visited[node] < visited[min_node]:
          min_node = node

    if min_node is None:
      break

    nodes.remove(min_node)
    current_weight = visited[min_node]

    for edge in graph.edges[min_node]:
      weight = current_weight + graph.distances[(min_node, edge)]
      if edge not in visited or weight < visited[edge]:
        visited[edge] = weight
        path[edge] = min_node

  return visited, path

def shortestPath(self,P,target):
  path = []
  while True:
    path.append(target)
    if target == self:
      break
    target = P[target]

  path.reverse()
  return path


def broadcast(s, self, neighbours_cost, neighbours_port):
  while True:
    seq = random.randint(0,10000)
    # seq = 200
    for i, v in enumerate(neighbours_port):
        value = {'from':self,'neighbours':neighbours_cost,'seq':seq}
        packet = pickle.dumps(value)
        s.sendto(packet, ('127.0.0.1',neighbours_port[v]))#v is its neighbours
        # print value['neighbours'][v]
        # print 'sent to %d' %(neighbours_port[v])
    time.sleep(1)


def rebroadcast(s, self, graph, port, neighbours_port, received_lsp):
  #gotta checks for incoming packet, and will rebroadcast while also adding more to the topology
  while True:
    rereceived = False
    # print 'waiting for lsp'
    packet, client = s.recvfrom(1024) #lsp doesn't go over 300
    message = pickle.loads(packet)
    broadcasted_neighbour = message['neighbours']
    source = message['from']

    #checks whether this is a message previously received or not
    if message['seq'] in received_lsp:
      rereceived = True

    #checks if lsp is from source
    if source != self and rereceived == False:
      # print message
      received_lsp.add(message['seq'])
      for i, v in enumerate(broadcasted_neighbour):
        graph.add_node(v)
        graph.add_edge(message['from'],v,broadcasted_neighbour[v])

      for i, v in enumerate(neighbours_port):
        if v != source:
          s.sendto(packet, ('127.0.0.1',neighbours_port[v]))
          # print 'rebroadcasted packet from %s' %(source)


def countShortest(self,graph,received_lsp):
  while True:
    time.sleep(30)
    visited, path = dijkstra(graph, self)
    for node in graph.nodes:
      string = ''
      route = shortestPath(self, path, node)
      for track in route:
        string = string+track
      if string != node:
        print 'least-cost path to node %s: %s and the cost is %.1f' %(node,string,round(visited[node],1))
    print ''
    received_lsp = set()#clears the previous 30 seconds worth of seq nums

#--------------------------------main is here----------------------------------
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

self = sys.argv[1]
port = int(sys.argv[2])
f = open(sys.argv[3],'r')
neighbours_cost = {}
neighbours_port = {}
received_lsp = set()
threads = []
num_of_neighbour = f.readline()
num_of_neighbour = int(num_of_neighbour)

host=''
s.bind((host,port))


graph = Graph()
graph.add_node(self)

for i in range (0,num_of_neighbour):
  read = f.readline()
  read = read.split()
  neighbours_cost[read[0]] = float(read[1])
  neighbours_port[read[0]] = int(read[2])
  graph.add_node(read[0])
  graph.add_edge(self, read[0], float(read[1]))

try:
  #broadcast thread
  print 'starting broadcast thread'
  t1 = Thread(target=broadcast, kwargs={'s':s,'self':self,'neighbours_cost':neighbours_cost,'neighbours_port':neighbours_port})
  t1.daemon = True
  #rebroadcast thread
  print 'starting rebroadcast thread'
  t2 = Thread(target=rebroadcast, kwargs={'s':s,'self':self,'graph':graph,'port':port,'neighbours_port':neighbours_port,'received_lsp':received_lsp})
  t2.daemon = True
  #dijkstra thread
  print 'starting dijkstra thread'
  t3 = Thread(target=countShortest, kwargs={'self':self,'graph':graph, 'received_lsp':received_lsp})
  t3.daemon = True
  threads.append(t1)
  threads.append(t2)
  threads.append(t3)
  t1.start()
  t2.start()
  t3.start()
  while True:
      i = 1
except KeyboardInterrupt:
  print 'keyboard interrupt triggered'
  s.close()
  sys.exit(1)
0

There are 0 best solutions below