我正在修改一些 modbus python 脚本以尝试学习它,但我似乎无法捕获 wireshark 上的流量。Modbus 客户端和服务器能否在同一台计算机上同时运行 localhost 并监听同一 TCP 端口 502?还是必须位于不同的机器上?
所有运行本地主机的客户端和服务器脚本基于pyModbusTCP在 Python 3.9 Windows 10 上启动和运行它出奇的容易。
这两个脚本来自 pyModbusTCP repo 的示例,我只是在我的 Windows 10 机器上本地运行它们,看看是否可以查看 Wireshark 上的流量。Pip 安装包,此代码将运行:
客户端.py
from pyModbusTCP.client import ModbusClient
import time
c = ModbusClient(host="localhost",
port=502,auto_open=True,
auto_close=False)
# main read loop
while True:
# read 10 bits (= coils) at address 0, store result in coils list
coils_l = c.read_coils(0, 10)
# if success display registers
if coils_l:
print('coil ad #0 to 9: %s' % coils_l)
else:
print('unable to read coils')
# sleep 2s before next polling
time.sleep(2)
服务器端
import argparse
from pyModbusTCP.server import ModbusServer, DataHandler
from pyModbusTCP.constants import EXP_ILLEGAL_FUNCTION
# some const
ALLOW_R_L = ['127.0.0.1', '192.168.0.10']
ALLOW_W_L = ['127.0.0.1']
# a custom data handler with IPs filter
class MyDataHandler(DataHandler):
def read_coils(self, address, count, srv_info):
if srv_info.client.address in ALLOW_R_L:
return super().read_coils(address, count, srv_info)
else:
return DataHandler.Return(exp_code=EXP_ILLEGAL_FUNCTION)
def read_d_inputs(self, address, count, srv_info):
if srv_info.client.address in ALLOW_R_L:
return super().read_d_inputs(address, count, srv_info)
else:
return DataHandler.Return(exp_code=EXP_ILLEGAL_FUNCTION)
def read_h_regs(self, address, count, srv_info):
if srv_info.client.address in ALLOW_R_L:
return super().read_h_regs(address, count, srv_info)
else:
return DataHandler.Return(exp_code=EXP_ILLEGAL_FUNCTION)
def read_i_regs(self, address, count, srv_info):
if srv_info.client.address in ALLOW_R_L:
return super().read_i_regs(address, count, srv_info)
else:
return DataHandler.Return(exp_code=EXP_ILLEGAL_FUNCTION)
def write_coils(self, address, bits_l, srv_info):
if srv_info.client.address in ALLOW_W_L:
return super().write_coils(address, bits_l, srv_info)
else:
return DataHandler.Return(exp_code=EXP_ILLEGAL_FUNCTION)
def write_h_regs(self, address, words_l, srv_info):
if srv_info.client.address in ALLOW_W_L:
return super().write_h_regs(address, words_l, srv_info)
else:
return DataHandler.Return(exp_code=EXP_ILLEGAL_FUNCTION)
if __name__ == '__main__':
# parse args
parser = argparse.ArgumentParser()
parser.add_argument('-H', '--host', type=str, default='localhost', help='Host (default: localhost)')
parser.add_argument('-p', '--port', type=int, default=502, help='TCP port (default: 502)')
args = parser.parse_args()
# init modbus server and start it
server = ModbusServer(host=args.host, port=args.port, data_hdl=MyDataHandler())
server.start()
在 Wireshark 上我绝对是新手,但选择我的以太网适配器时肯定有流量:
然后尝试过滤 modbus tcp.port 502 没有任何结果...有什么可以尝试的吗?
该脚本似乎正在按客户端脚本控制台打印的方式运行:
coil ad #0 to 9: [False, False, False, False, False, False, False, False, False, False]
coil ad #0 to 9: [False, False, False, False, False, False, False, False, False, False]
coil ad #0 to 9: [False, False, False, False, False, False, False, False, False, False]
答案1
我正在修改一些 modbus python 脚本以尝试学习它,但我似乎无法在 wireshark 上捕获流量。Modbus 客户端和服务器是否可以在同一台计算机上运行 localhost 并监听同一个 TCP 端口 502?或者它们必须在不同的机器上?
TCP 客户端不听在 TCP 端口 502 上 – 它仅连接到服务器的端口 502。(通常 TCP 中的客户端端口是随机选择的,因此模块甚至没有它的参数。)它通常应该以与在本地主机上托管 Web 服务器的方式相同。
在 Wireshark 上我绝对是新手,但选择我的以太网适配器时肯定有流量:
这看起来像 HTTPS 流量(端口 443 上的一些 TLS 和一些 QUIC)。
然后尝试过滤 modbus tcp.port 502,没有任何结果
由于您连接到同一台机器,您的流量实际上并不经过任何外部以太网接口(即使您使用其 IP 地址) - 它与“本地主机”流量的处理方式相同。
因此,您的 TCP 数据包可能会出现在“环回”接口上 - 尽管在 Windows 上捕获环回数据包并不总是有效。