我写了两个名为runner.py和connect.py的python脚本。 runner脚本启动具有特定端口的流量模拟,另一个连接并能够发送命令。这两个脚本在我的python IDE中运行良好。但我想从java启动这两个脚本来接收数据。
import org.python.core.PyInstance;
import org.python.util.PythonInterpreter;
import org.python.core.PyObject;
import org.python.core.PyString;
public class PythonHandler {
PythonInterpreter interpreter = null;
String script_dir;
public PythonHandler() {
PythonInterpreter.initialize(System.getProperties(), System.getProperties(), new String[0]);
this.interpreter = new PythonInterpreter();
this.script_dir = System.getProperty("user.dir");
}
void execfile(final String fileName) {
this.interpreter.execfile(fileName);
}
PyInstance createClass(final String className, final String opts) {
return (PyInstance) this.interpreter.eval(className + "(" + opts + ")");
}
/**
* This method will start the python script runner.py
* NOTE: doesn't work if there is not a main method in the python script
*/
public void startRunner() {
String runner_dir = script_dir + "\\src\\de\\uniol\\inf\\is\\odysseus\\pgtaxi\\traci\\traci4python\\runner.py";
PythonHandler ie = new PythonHandler();
ie.execfile(runner_dir);
}
/**
* This method will start the python script connect.py
* NOTE: doesn't work if there is not a main method in the python script
*/
public void startConnect() {
String connect_dir = script_dir
+ "\\src\\de\\uniol\\inf\\is\\odysseus\\pgtaxi\\traci\\traci4python\\connect.py";
PythonHandler ie = new PythonHandler();
ie.execfile(connect_dir);
}
/**
* This method will start the python script connect.py
* If there is not a main method you can run a specific function
*
* @param function
* name of the function you want to start
*/
public void callConnectFunction(String function) {
String connect_dir = script_dir
+ "\\src\\de\\uniol\\inf\\is\\odysseus\\pgtaxi\\traci\\traci4python\\connect.py";
PythonHandler ie = new PythonHandler();
ie.execfile(connect_dir);
PyInstance run = ie.createClass("Connection", "None");
run.invoke(function);
}
/**
* This method will start the python script runner.py
* If there is not a main method you can run a specific function
*
* @param function
* name of the function you want to start
*/
public void callRunnerFunction(String function) {
String runner_dir = script_dir + "\\src\\de\\uniol\\inf\\is\\odysseus\\pgtaxi\\traci\\traci4python\\connect.py";
PythonHandler ie = new PythonHandler();
ie.execfile(runner_dir);
PyInstance run = ie.createClass("Runner", "None");
run.invoke(function);
}
}
两个脚本都启动但在connect.py中发生错误。我不知道为什么我能够从python IDE运行脚本而不是从我的java代码运行脚本。 以下是python脚本中的代码:
runner.py
import sys
import subprocess
import os
PORT = 8873
class Runner:
__gui = None
def __init__(self, gui):
self.__gui = gui
print "Starting runner..."
def runLocal(self):
sumoBinary = os.path.abspath(os.curdir)
sumoBinary = sumoBinary.split('de.uniol.inf.is.odysseus.pgtaxi')[0]
sumoBinary = sumoBinary + 'de.uniol.inf.is.odysseus.pgtaxi\\sumo\\bin\\sumo-gui'
scenario = os.path.abspath(os.curdir)
scenario = sumoBinary.split('de.uniol.inf.is.odysseus.pgtaxi')[0]
scenario = scenario + 'de.uniol.inf.is.odysseus.pgtaxi\\scenario\\oldenburg.sumocfg'
sumoProcess = subprocess.Popen([sumoBinary, "-c", scenario, "--remote-port", str(PORT)], stdout=sys.stdout, stderr=sys.stderr)
if __name__ == '__main__':
conn = Runner('None')
conn.runLocal()
connect.py
import sys
import os
PORT = 8873
class Connection:
__gui = None
def __init__(self, gui):
self.__gui = gui
print "Starting connect..."
def initTraci(self):
tools = os.path.abspath(os.curdir)
tools = tools.split('de.uniol.inf.is.odysseus.pgtaxi')[0]
tools = tools + 'de.uniol.inf.is.odysseus.pgtaxi\\sumo\\tools'
sys.path.append(tools)
import traci
traci.init(PORT)
step = 0
while step < 1000:
traci.simulationStep()
step += 1
traci.close()
sys.stdout.flush()
def getFreePort(self):
tools = os.path.abspath(os.curdir)
tools = tools.split('de.uniol.inf.is.odysseus.pgtaxi')[0]
tools = tools + 'de.uniol.inf.is.odysseus.pgtaxi\\sumo\\tools'
sys.path.append(tools)
import sumolib
PORT = sumolib.miscutils.getFreeSocketPort()
if __name__ == '__main__':
conn = Connection('None')
conn.initTraci()
我得到了这个例外:
Exception in thread "MainThread" Traceback (most recent call last):
File "C:\Users\FEPREUSS\Desktop\PG\workspace\de.uniol.inf.is.odysseus.pgtaxi\src\de\uniol\inf\is\odysseus\pgtaxi\traci\traci4python\connect.py", line 44, in <module>
conn.initTraci()
File "C:\Users\FEPREUSS\Desktop\PG\workspace\de.uniol.inf.is.odysseus.pgtaxi\src\de\uniol\inf\is\odysseus\pgtaxi\traci\traci4python\connect.py", line 25, in initTraci
traci.init(PORT)
File "C:\Users\FEPREUSS\Desktop\PG\workspace\de.uniol.inf.is.odysseus.pgtaxi\sumo\tools\traci\__init__.py", line 65, in init
return getVersion()
File "C:\Users\FEPREUSS\Desktop\PG\workspace\de.uniol.inf.is.odysseus.pgtaxi\sumo\tools\traci\__init__.py", line 82, in getVersion
return _connections[""].getVersion()
AttributeError: 'NoneType' object has no attribute 'getVersion'
导致激发的lib中的两种方法:
def init(port=8813, numRetries=10, host="localhost", label="default"):
"""
Establish a connection to a TraCI-Server and store it under the given
label. This method is not thread-safe. It accesses the connection
pool concurrently.
"""
_connections[label] = connect(port, numRetries, host)
switch(label)
return getVersion()
def getVersion():
return _connections[""].getVersion()
希望有人可以帮助我。
答案 0 :(得分:0)
你偶然发现了jython bug被SUMO屏蔽掉,隐藏了失败的套接字连接的错误消息。不幸的是,除了在第49行编辑SUMO / tools / traci / connection.py之外,你不能轻易解决它。
只需将self._socket = socket()
替换为
self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
还将解决方法提交到SUMO存储库。