python使用socket进行多线程收发与路径计算模拟路由器网络

课设作业,使用多线程方式通过一个端口上的socket同时进行广播信息,接收信息,Dijkstra路径计算来模拟一个网络中路由器的简单行为。
配置文件中包含:
路由器名称与运行端口
初始所知的附近路由器数量
初始所知的附近路由器名称,距离与运行端口地址
例如configAE.txt文件:

AE 7001
2
BW 3.1 7003
DR 2.7 7007

windows下运行启动脚本:

start cmd /k "python router.py configAE.txt"

代码文件router.py

#!/usr/bin/python3.7import socket
import sys
import threading
import time
import operator
import copy# 获取精度到秒的时间戳
def get_time():return int(time.time())# 创建发送的信息
def create_msg():msg = router_id + ' ' + str(router_port) + ' ' + str(get_time()) + '\n'msg = msg + "neighbour\n"for ID in neighbour_list.keys():msg = msg + ID + ' ' + str(neighbour_list[ID].get_port()) + ' '\+ str(neighbour_list[ID].get_cost()) + '\n'return msg# 读取接收的信息
def deal_msg(msg):if msg == "":return -1lines = msg.split("\n")creater = lines[0].split(" ")creater_id = creater[0]creater_port = creater[1]creater_time = int(creater[2])# if it is created by itselfif creater_id == router_id:return -1# if it is a path informationif lines[1] == "neighbour":# if it is a recur routerif creater_id in dead_list:router_recieve_list[creater_id] = creater_timedead_list.remove(creater_id)temp_dic = {}for line in lines[2:-1]:info = line.split(" ")temp_dic[info[0]] = [int(info[1]),float(info[2])]if operator.eq(temp_dic, all_route[creater_id]) != 0:all_route[creater_id] = temp_dicreturn creater_id# if it is a new routerif creater_id not in router_recieve_list.keys()\or creater_id not in all_route.keys():router_recieve_list[creater_id] = creater_timetemp_dic = {}for line in lines[2:-1]:info = line.split(" ")temp_dic[info[0]] = [int(info[1]),float(info[2])]all_route[creater_id] = temp_dicreturn 0# if just normal updateelse:# if it is an old message which do not need to deal withif creater_time <= router_recieve_list[creater_id]:return -1# if it is a useful messageelse:router_recieve_list[creater_id] = creater_timetemp_dic = {}for line in lines[2:-1]:info = line.split(" ")temp_dic[info[0]] = [int(info[1]),float(info[2])]if operator.eq(temp_dic, all_route[creater_id]) == 0:return 0 # do nothing# replace itelse:all_route[creater_id] = temp_dicreturn 0       elif lines[1] == "dead":if creater_id not in router_recieve_list.keys():router_recieve_list[creater_id] = creater_timeelif creater_time <= router_recieve_list[creater_id]:return -1if lines[2] not in dead_list and lines[2] != router_id:dead_list.append(lines[2])return 0elif lines[1] == "resur":if creater_id not in router_recieve_list.keys():router_recieve_list[creater_id] = creater_timeelif creater_time <= router_recieve_list[creater_id]:return -1if lines[2] in dead_list:  dead_list.remove(lines[2])return 0# Dijkstra算法与打印输出
def Dijkstra():# delete all the dead routetemp_routers = copy.deepcopy(all_route)for ID in dead_list:if ID != router_id:if ID in temp_routers.keys():del temp_routers[ID]for router in temp_routers.keys():if ID in temp_routers[router].keys():del temp_routers[router][ID]# start caculateunvisit_nodes = [ID for ID in temp_routers.keys()]visited_nodes = []# initializefor ID in unvisit_nodes:# {ID: previous node, cost}cost_list[ID] = ['', float('inf')]# first pointcost_list[router_id] = ['', 0.0]# all neighboursfor ID in all_route[router_id].keys():cost_list[ID] = [router_id, all_route[router_id][ID][1]]unvisit_nodes.remove(router_id)visited_nodes.append(router_id)# start loopwhile len(unvisit_nodes) != 0:# find the shortest unvisit nodemin_cost = float('inf')min_id = ''for ID in unvisit_nodes:if cost_list[ID][1] <= min_cost:min_cost = cost_list[ID][1]min_id = ID# start from min_id, for all neighboursfor ID in all_route[min_id].keys():if ID in unvisit_nodes:cost = round(min_cost + all_route[min_id][ID][1], 6)# if it is a shorter pathif cost < cost_list[ID][1]:cost_list[ID] = [min_id, cost]# mark the nodeunvisit_nodes.remove(min_id)visited_nodes.append(min_id)# print resultprint("I am Router " + router_id)visited_nodes.remove(router_id)visited_nodes.sort()for ID in visited_nodes:path = IDtemp = IDwhile cost_list[temp][0] != '':path = cost_list[temp][0] + pathtemp = cost_list[temp][0]print("Least cost path to router " + ID + ": " \+ path + " and the cost is " + str(cost_list[ID][1]))print()# 为记录中的路由器创建一个类来记录
class router:def __init__(self, ID, cost, port):self.ID = IDself.cost = costself.port = portdef get_id(self):return self.IDdef get_cost(self):return self.costdef get_port(self):return self.port# 广播线程
class broadcast(threading.Thread):def __init__(self, threadID, name, interval, soc):threading.Thread.__init__(self)self.threadID = threadIDself.name = nameself.interval = intervalself.soc = socdef run(self):while True:msg = create_msg()msg = msg.encode(encoding='UTF-8')for ID in neighbour_list.keys():self.soc.sendto(msg, ("127.0.0.1", neighbour_list[ID].get_port()))time.sleep(self.interval)# 接收线程
class recieve(threading.Thread):def __init__(self, threadID, name, soc):threading.Thread.__init__(self)self.threadID = threadIDself.name = nameself.soc = socdef run(self):while True:msg = ""addr = ""try:data, addr = self.soc.recvfrom(2048)msg = data.decode(encoding='UTF-8')except:pass#print(msg,"from",addr)result = deal_msg(msg)if result == 0: # if it is not an old message, broadcast itfor ID in neighbour_list.keys():self.soc.sendto(data, ("127.0.0.1", neighbour_list[ID].get_port()))# some router is recurelif type(result) == str:recur_msg = router_id + ' ' + str(router_port) + ' ' + str(get_time()) + '\n'recur_msg = recur_msg + "resur\n" + result + "\n"recur_msg = recur_msg.encode(encoding='UTF-8')for ID in neighbour_list.keys():self.soc.sendto(recur_msg, ("127.0.0.1", neighbour_list[ID].get_port()))            # for test#print(msg,"deal with from",addr)# 计算线程
class calculate(threading.Thread):def __init__(self, threadID, name, soc):threading.Thread.__init__(self)self.threadID = threadIDself.name = nameself.soc = socdef run(self):while True:time.sleep(ROUTE_UPDATE_INTERVAL)now = get_time()for ID in neighbour_list.keys():# if a router is deadif ID in router_recieve_list.keys():if now - router_recieve_list[ID] > 10 and ID not in dead_list:dead_list.append(ID)dead_msg = router_id + ' ' + str(router_port) + ' ' + str(get_time()) + '\n'dead_msg = dead_msg + "dead\n" + ID + "\n"dead_msg = dead_msg.encode(encoding='UTF-8')for ID in neighbour_list.keys():self.soc.sendto(dead_msg, ("127.0.0.1", neighbour_list[ID].get_port()))  Dijkstra()# 读取文件信息
filepath = sys.argv[1]# set parameter
UPDATE_INTERVAL = 1
ROUTE_UPDATE_INTERVAL = 30router_id = 0
router_port = 0
# total number of neighbours
neighbour_number = 0
# {ID: class router}, only for neighbours
neighbour_list = {}
# {ID: timestamp}, last time recieve broadcast created by the router
router_recieve_list = {}
# all routers in the whole net
# like {A: {B:[5001,2],C:[5003,5]}}, means A to B is 2, only A's neighbours
all_route = {}
# dead router
dead_list = []
# # {ID: previous node, cost}, store the result of Dijkstra’s algorithm
cost_list = {}with open(filepath) as input_file:input_lines = input_file.readlines()router_id = input_lines[0].split(" ")[0]router_port = int(input_lines[0].split(" ")[1])neighbour_number = int(input_lines[1])all_route[router_id] = {}for i in range(0, neighbour_number):line = input_lines[i+2]line = line.split(" ")neighbour_id = line[0]neighbour_cost = float(line[1])neighbour_port = int(line[2])neighbour_list[neighbour_id] = router(neighbour_id, neighbour_cost, neighbour_port)all_route[router_id][neighbour_id] = [neighbour_port, neighbour_cost]
# 文件信息读取完毕# 创建线程
soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
soc.bind(("127.0.0.1", router_port))
thread_broadcast = broadcast(1, "broadcast", UPDATE_INTERVAL, soc)
thread_recieve = recieve(2, "recieve", soc)
thread_calculate = calculate(3, "calculate", soc)# 启动线程
thread_broadcast.start()
thread_recieve.start()
thread_calculate.start()

python使用socket进行多线程收发与路径计算模拟路由器网络相关推荐

  1. 「Python」socket指南

    开始 网络中的 Socket 和 Socket API 是用来跨网络的消息传送的,它提供了 进程间通信(IPC) 的一种形式.网络可以是逻辑的.本地的电脑网络,或者是可以物理连接到外网的网络,并且可以 ...

  2. Python中socket解读

    操作系统底层原理 操作系统:(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在"裸机"上的最基本的系统软件,任何其他软件都必须 ...

  3. Python学习,python中socket解读

    操作系统底层原理 操作系统:(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在"裸机"上的最基本的系统软件,任何其他软件都必须 ...

  4. Python:socket编程教程

    ocket是基于C/S架构的,也就是说进行socket网络编程,通常需要编写两个py文件,一个服务端,一个客户端. 首先,导入Python中的socket模块: import socket Pytho ...

  5. Python的socket网络编程(一)

    (注:本文部分内容摘自互联网,由于作者水平有限,不足之处,还望留言指正.) 先写首诗,抒抒情. 一. 食堂.校园 见过你那么多次 卑微的我 只敢偷偷瞄上一眼 心扑通 扑通 春天真好 不是么 二. 学子 ...

  6. Python 多进程开发与多线程开发

    我们先来了解什么是进程? 程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运行的静态描述文本:进程 ...

  7. 用python做双人五子棋_基于python的socket实现单机五子棋到双人对战

    基于python的socket实现单机五子棋到双人对战,供大家参考,具体内容如下 本次实验使用python语言.通过socket进行不同机器见的通信,具体可以分为以下四步:1.创建ServerSock ...

  8. delphi 多个线程 多个进度条_多线程有哪些优点?- Python每日3题(多线程专题)

    这里是Python7编程挑战-多线程专题! 每天学习3个问题,包括初级,中级,高级问题各1个. 今天是第2天!一起来呀,就7天! 每日3题是麦叔的面试系列专题之一,每天包括初级,中级,高级难度题目各一 ...

  9. python中用socket检测端口_python基于socket函数实现端口扫描

    本文实例为大家分享了python基于socket实现端口扫描的具体代码,供大家参考,具体内容如下 自学Python一段时间,写个端口扫描器练练手.有什么不足之处,请见谅 这是基于socket函数对端口 ...

最新文章

  1. readelf小尝试
  2. python 类-Python 类class定义 方法与属性教程
  3. python常用内置函数总结-python常用内置函数
  4. Yet Another Problem About Pi
  5. 期末考试前的预习,科目:化工设备与反应器(3)
  6. [改善Java代码]构造函数尽量简化
  7. Atomic Integer 原理分析-get方法
  8. 关于表单回车自动提交的讨论
  9. 购物车的功能——CSS源码
  10. linux ssh和sftp区别,Linux SSH和SFTP配置
  11. mysql中 视图的优缺点_SQL中使用视图的优点和缺点是什么
  12. 使用Scrapy,帮你快速抓取网页数据(代码可下载)!
  13. js练习——动态控制表格中得行
  14. 水利水电专业英语(2.5k行超全)
  15. 仅以此贴,献给兄弟们的《光辉岁月》
  16. 前端程序员成长的记录及被某IT外包公司套路的经历
  17. 计算机网络求校验码,计算机网络课程设计校验码的计算
  18. Python练习:炉石传说荣誉室返尘最优策略
  19. 用 Python 分析资产收益的典型化事实
  20. mysql purge master logs_PURGE MASTER LOGS语法--MySql数据库

热门文章

  1. 股票程序化交易如何理解自己的交易系统?
  2. 杭电ACM2002题-------C语言
  3. C++中的字符串输入输出
  4. 利用C语言打印9*9乘法表
  5. 车辆重识别:Flare-Aware Cross-modal Enhancement Network for Multi-spectral Vehicle Re-identification
  6. 基于STM32单片机驱动HX711的代码分享,仅供参考
  7. HTML介绍及第一次编写网页
  8. 第二课计算机ppt,学信息技术课件 第2课 认识计算机课件.ppt
  9. 图文详解哈希树-Merkle Tree(默克尔树)算法解析
  10. 电影《人工智能》观后感