从Mininet Python API启动的脚本会在一段时间后停止工作

时间:2019-02-09 10:35:58

标签: python mininet pymodbus

我正在尝试在 mininet 中编写一些自动化测试,目的是:

  • 创建简单的拓扑
  • 在服务器和客户端之间运行一些通信
  • 收集一些数据并过一段时间后停止

我可以通过运行miniedit配置并在连接到主机的两个终端上手动启动服务器和客户端脚本来运行这些测试,

但是,我尝试使用Python API进行操作,但是在交换了一些数据包后,我在主机上启动的脚本无法正常工作。正如我之前所说的,如果我在两个终端上手动启动这两个脚本,它们会很好地工作,所以我认为可能还有另一个问题。 我本来以为这可能是我用来实现服务器和客户端脚本( pyModbus pyModbusTCP )的模块上的错误,但事实是它们在工作时没有问题手动启动会导致我认为通过Python API启动脚本的方式可能做错了。

这是启动模拟的脚本:

#!/usr/bin/python                                                                            

from mininet.topo import Topo
from mininet.net import Mininet
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel

# The first argument is the project path
clientPath = sys.argv[1] + 'test/integration/test_training/client.py'
serverPath = sys.argv[1] + 'test/integration/test_training/server.py'

class SingleSwitchTopo(Topo):
  def build(self, n=2):
    switch = self.addSwitch('s1')
    for h in range(n):
      host = self.addHost('h%s' % (h + 1))
      self.addLink(host, switch)

def test():
  topo = SingleSwitchTopo(n=2)
  net = Mininet(topo)
  net.start()
  hosts = net.hosts
  server = hosts[0]
  client = hosts[1]
  # Start the server process in the background
  server.sendCmd('python3 ' + serverPath)
  # Start the client and print the output
  client.cmdPrint('python3 ' + clientPath)
  # Here there would be the rest of the test

if __name__ == '__main__':
  setLogLevel('info')
  test()

启动此脚本后,日志显示客户端在一段时间内正确接收了响应。但是,在某个时候服务器将总是开始发送空响应,而当我在miniedit配置上手动运行脚本时,这种情况永远不会发生。

这些是服务器和客户端脚本(这些是简单的pyModbus和pyModbusTCP脚本,作为默认示例提供):

服务器

此服务器基本上会定期更新一些值并侦听查询。

#!/usr/bin/python3

from pymodbus.server.async import StartTcpServer
from pymodbus.device import ModbusDeviceIdentification
from pymodbus.datastore import ModbusSequentialDataBlock
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext

from twisted.internet.task import LoopingCall

server_ip = '10.0.0.1'
server_port = 502
start_address = 1
final_address = [1]*100

#LOG
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

init_val = 0

# updating server function
def updating_server(a):
    log.debug("updating PLC registers..")
    context = a[0]
    register = 4
    slave_id = 0x00
    address = 0
    values = context[slave_id].getValues(register, address, count=5)
    values = [v + 1 for v in values]
    log.debug("new values: " + str(values))
    context[slave_id].setValues(register, address, values)

store = ModbusSlaveContext(
    di = ModbusSequentialDataBlock(0, [1]*100),
    co = ModbusSequentialDataBlock(0, [2]*100),
    hr = ModbusSequentialDataBlock(0, [3]*100),
    ir = ModbusSequentialDataBlock(0, [init_val]*100))
context = ModbusServerContext(slaves=store, single=True)

identity = ModbusDeviceIdentification()
identity.VendorName = 'Pymodbus'
identity.ProductCode = 'PM'
identity.VendorUrl = 'http://github.com/bashwork/pymodbus/'
identity.ProductName = 'Pymodbus Server'
identity.ModelName = 'Pymodbus Server'
identity.MajorMinorRevision = '1.0'

#server run and update
time = 0.5
loop = LoopingCall(f=updating_server, a=(context,))
loop.start(time, now=False)

StartTcpServer(context, identity=identity, address=(server_ip, server_port))

客户

此客户端连接到服务器并定期发送查询。

#!/usr/bin/python3

from pyModbusTCP.client import ModbusClient
import time

server_ip = '10.0.0.1'
server_port = 502

c = ModbusClient(host=server_ip, port=server_port, auto_open=True)
c.debug(True)

while True:
  if c.is_open():
    # read 5 input registers starting at address 0
    values = c.read_input_registers(0, 5)
    print(values)
    time.sleep(0.1)
  else:
    c.open()
    time.sleep(0.5)

在这个问题上,我花了很长时间才找到解决方法。我想念什么吗?

0 个答案:

没有答案