【问题标题】:How does port numbering works for receiving MODBUS TCP packets?端口编号如何用于接收 MODBUS TCP 数据包?
【发布时间】:2016-11-21 20:56:49
【问题描述】:

我正在我的微控制器 (MSP432) 上运行一个应用程序,它将数据写入以太网电缆以将其发送到 PC。

我正在使用 Packet sender 查看从 MC 在 PC 上的端口 (502) 上接收到的数据。 Data received on PC

正如我们在上图中看到的,MC 的端口号随着每个数据包的发送而递增。 当它达到最大数量时会发生什么? 它会在其他端口号重新启动并继续该过程还是会停止?

Edit1:从http://myarduinoprojects.com/modbus.html使用的Modbus协议库

编辑2: 每次我有一个新数据要通过 MODBUS 发送时,都会调用这个函数。 Mb.Req(MB_FC_WRITE_MULTIPLE_REGISTERS, 0,11,0);

 if (MbmClient.connect(ServerIp,502)) {
  digitalWrite(GREEN_LED, HIGH);
#if DEBUG
  //Serial.println("connected with modbus slave");
 // Serial.print("Master : ");
  for(int i=0;i<MbmByteArray[5]+6;i++) {
    if(MbmByteArray[i] < 16){
    //Serial.print("0");
  }
    //Serial.print(MbmByteArray[i],HEX);
    if (i != MbmByteArray[5]+5) {
    //Serial.print(".");
  } else {
  //Serial.println();
  }
  }
#endif    
MbmClient.write(MbmByteArray,13+(Count*2));

MbmCounter = 0;
MbmByteArray[7] = 0;
MbmPos = Pos;
MbmBitCount = Count;

*state= true;
MbmClient.stop();
delay(100);
digitalWrite(GREEN_LED, LOW);   
} else {  

  *state= false;
  MbmClient.stop();
}

【问题讨论】:

  • 有没有办法查看所有的 TCP 消息?我的意思是包括3次握手?在 MC 中,如何发送消息?使用 TCP 套接字?还是只是发送一个以太网帧,其中包含一个包含 TCP 消息的 IP 数据报?
  • 我使用 IP 地址(PC 上的以太网 IP)、端口号建立了连接。这是你问的吗?。
  • 看起来每条消息都使用一个新连接,这很糟糕。端口号会回绕,或者如果它们使用得太快,客户端会出现绑定错误。
  • @EJP:所以一个好办法是使用同一个端口?另外为了快速连接和传输,是否建议从同一端口连接?
  • 不,使用相同的连接。这使得不可能使用多个源端口。您根本不应该在客户端中指定源端口。系统会给你一个。

标签: networking port msp430 modbus-tcp


【解决方案1】:

您似乎在使用this Modbus example 我从未使用过,但我想这是因为代码中的目标端口与your sniffing image 中的目标端口相同:502

可能你在重复调用这个方法:

void MgsModbus::Req(MB_FC FC, word Ref, word Count, word Pos)

在这个方法里面你可以看到这一行:

if (MbmClient.connect(ServerIp,502)) { 
...

因此,每次调用该函数时,都会打开一个新连接。当您通过套接字打开连接时,操作系统或网络堆栈需要选择发送 TCP 消息的源端口和 IP 地址。

这就是为什么您总是看到一个新的源端口并且该端口正在增加。这就是所谓的临时端口。您正在使用的 TCP 堆栈如何选择源端口取决于实现,尽管从某个端口开始并且每次打开连接时,它都会选择下一个可用端口。

如果堆栈编程良好,很可能您的 TCP 堆栈将环绕并从 1024 向上的某个特定端口开始(前 1024 个端口受到限制)。我看到的代码似乎用这个函数关闭了端口:

MbmClient.stop()

您需要检查端口,在使用后是否关闭。否则,在某些时候,您将耗尽可用端口(资源泄漏)。

如果你想让你的socket绑定到特定的源端口,你需要使用类似于Linux socket bind的函数

现在,更明智的方法是始终使用相同的连接。您可能需要修改该示例。

【讨论】:

  • 我在原帖上添加了代码。因此,每当我通过调用 MbmClient.connect(ServerIp,502) 建立连接时,我也会关闭连接。那么为什么它每次仍然连接到不同的端口呢?您能否指导我如何继续使用相同的端口方法。谢谢
  • @JanakVarma,每次您的应用程序启动连接时,它都会选择一个ephemeral port。这通常是随机选择的,但您的 TCP 实现似乎不是那样做的。您的应用程序要求 TCP 为其选择源端口。您可以告诉 TCP 使用哪个端口,而不是让 TCP 选择端口。
  • @JanakVarma,我认为我的回答很清楚地解释了为什么它总是使用不同的源端口。它始终连接到同一个目标端口 502。我添加了更多措辞以使其更清晰。您还可以查看 Ron Maupin 的评论并阅读他提供的链接。
猜你喜欢
  • 2014-06-07
  • 2021-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多