1. 程式人生 > >異形Modbus客戶端 和 異形modbus服務器之間的通訊 偵聽模式的modbus-tcp客戶端通訊

異形Modbus客戶端 和 異形modbus服務器之間的通訊 偵聽模式的modbus-tcp客戶端通訊

讀取 blog 網絡請求 交互 實現 highlight box tcpclient install

前言


本文將使用一個Github公開的組件技術來實現一個異形ModBus TCP的客戶端,方便的對異形Modbus tcp的服務器進行讀寫,這個服務器可以是電腦端C#設計的,也可以是特殊設備實現的,也可以是其他任何支持這個通信協議的服務器。

github地址:https://github.com/dathlin/HslCommunication 如果喜歡可以star或是fork,還可以打賞支持。

本文下面的DEMO的項目的源代碼都在這個地址裏面

在Visual Studio 中的NuGet管理器中可以下載安裝,也可以直接在NuGet控制臺輸入下面的指令安裝

Install-Package HslCommunication

NuGet安裝教程 http://www.cnblogs.com/dathlin/p/7705014.html

技術支持QQ群:592132877 (組件的版本更新細節也將第一時間在群裏發布)組件API地址:http://www.cnblogs.com/dathlin/p/7703805.html

關於異形模式,也叫偵聽式客戶端


通常的模式都是服務器客戶端模式,由客戶端發起連接,然後和服務器進行數據交換實現的,但是實際中還有一種模式就是,由服務器主動發起對客戶端的連接,然後客戶端再執行對服務器的數據交互,聽著可能會有些別扭,但是確實存在的,通常應用於一些,工業現場的4G上網的設備。當然也可以實現自定義的一些功能操作。需要慢慢的看下面的代碼。

異形模式主要分兩部分組成,偵聽服務器,異形modbus-tcp客戶端。

偵聽服務器負責,偵聽網絡請求和Alien協議驗證,通過之後將連接拋給異形modbus-tcp客戶端使用。

註冊包及Alien協議


在modbus服務器連上雲服務器的ip及端口地址後,需要發送一條註冊包信息,這條註冊包信息需要遵循如下的協議,稱為Alien協議,其他的協議支持需要二次定制開發完成。本協議詳細如下:

註冊包共28個字節,

// 註冊包
0x48 0x73 0x6E 0x00 0x17 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 0x39 0x30 0x31 0x00 0x00 0x00 0x00 0x00 0x00 0xC0 0xA8 0x00 0x01 0x17 0x10
+------------------+ +----+ +-----+ +-----------------------------------------------------------------------------+ +----------------------------------------+ +---------------------------+ +-------------+
+ 固定消息頭 + 備用 後面長度 DTU碼 12345678901 (唯一標識,比如手機號) 登錄密碼(不受信的排除) Ip:192.168.0.1 端口10000
+------------------+ +----+ +-----+ +----------------------------------------------------------------------------+ +-----------------------------------------+ +-------------------------+ +--------------+

// 返回消息,下面是正常的註冊成功的信息

0x48 0x73 0x6E 0x00 0x01 0x00
+----------------- + +----+ +----+ +----+
固定消息頭 備用 後面長度 結果代碼

// 結果代碼

0x00: 登錄成功
0x01: DTU重復登錄
0x02: DTU禁止登錄
0x03: 密碼驗證失敗

偵聽請求


第一步需要先建立偵聽服務器,觸發的事件為什麽會有兩個參數是因為當你有多個服務器的時候,就可以共同關聯一個方法,然後通過network來區分信號,核心代碼如下所示,到時候只要調用 NetworkAlienStart 方法即可

        private NetworkAlienClient networkAlien = null;

        private void NetworkAlienStart( int port )
        {
            networkAlien = new NetworkAlienClient( );
            networkAlien.OnClientConnected += NetworkAlien_OnClientConnected;
            networkAlien.LogNet = logNet;
            networkAlien.ServerStart( port );
        }

        private void NetworkAlien_OnClientConnected( NetworkAlienClient network , AlienSession session )
        {
            // 當有連接的時候會觸發這個方法
        }

異形Modbus-Tcp


建立一個異形客戶端,數據交互塊和,原來的客戶端幾乎是一模一樣的,僅僅是連接原理不一樣,設置成異形客戶端之後,就不在負責連接的功能了,變成了被動設置連接對象的功能。代碼也是很方便的

1. 先定義對象

private ModbusTcpNet busTcpClient = null;

2. 實例化,IP和端口隨便指定,反正對於異形客戶端是沒有用途的,但是站號還是有用的

busTcpClient = new ModbusTcpNet( textBox1.Text, port, station );

3. 設置為異形模式,當然先不設置也可以,可以調到第四步再進行設置

busTcpClient.ConnectServer( null );

4. 修改請求偵聽的回調方法

private void NetworkAlien_OnClientConnected( NetworkAlienClient network, AlienSession session )
        {
            busTcpClient.ConnectServer( session );
        }

當有modbus服務器連接上來的時候,就觸發該方法,就可以通過busTcpClient對服務器進行數據讀寫了。上面演示的情況僅僅是一個客戶端的情況,如果有多個客戶端呢?我們可以通過唯一的識別碼來相互關聯,對於每個傳進來的session數據,還包含了連接請求的DTU唯一碼,我們就可以進行判定了。

我們先設置異形客戶端的唯一碼

busTcpClient.ConnectionId = "12345678901"

再修改回調方法

private void NetworkAlien_OnClientConnected( NetworkAlienClient network , AlienSession session )
        {
            if(session.DTU == busTcpClient.ConnectionId)
            {
                busTcpClient.ConnectServer( session );
            }
        }

通常的方法都是先定義好自己的客戶端數組,並指定DTU碼,然後批量的對數組進行數據請求操作。

具體的數據請求操作,請參照正常的Modbus-TCP博客,

http://www.cnblogs.com/dathlin/p/7885368.html

下面隨便貼一點示例代碼

private void userButton30_Click(object sender, EventArgs e)

{

    // 讀取操作

    bool coil100 = busTcpClient.ReadCoil("100").Content;   // 讀取線圈100的通斷

    short short100 = busTcpClient.ReadInt16("100").Content; // 讀取寄存器100的short值

    ushort ushort100 = busTcpClient.ReadUInt16("100").Content; // 讀取寄存器100的ushort值

    int int100 = busTcpClient.ReadInt32("100").Content;      // 讀取寄存器100-101的int值

    uint uint100 = busTcpClient.ReadUInt32("100").Content;   // 讀取寄存器100-101的uint值

    float float100 = busTcpClient.ReadFloat("100").Content; // 讀取寄存器100-101的float值

    long long100 = busTcpClient.ReadInt64("100").Content;    // 讀取寄存器100-103的long值

    ulong ulong100 = busTcpClient.ReadUInt64("100").Content; // 讀取寄存器100-103的ulong值

    double double100 = busTcpClient.ReadDouble("100").Content; // 讀取寄存器100-103的double值

    string str100 = busTcpClient.ReadString("100", 5).Content;// 讀取100到104共10個字符的字符串

 

    // 寫入操作

    busTcpClient.WriteCoil("100", true);// 寫入線圈100為通

    busTcpClient.Write("100", (short)12345);// 寫入寄存器100為12345

    busTcpClient.Write("100", (ushort)45678);// 寫入寄存器100為45678

    busTcpClient.Write("100", 123456789);// 寫入寄存器100-101為123456789

    busTcpClient.Write("100", (uint)123456778);// 寫入寄存器100-101為123456778

    busTcpClient.Write("100", 123.456);// 寫入寄存器100-101為123.456

    busTcpClient.Write("100", 12312312312414L);//寫入寄存器100-103為一個大數據

    busTcpClient.Write("100", 12634534534543656UL);// 寫入寄存器100-103為一個大數據

    busTcpClient.Write("100", 123.456d);// 寫入寄存器100-103為一個雙精度的數據

    busTcpClient.Write("100", "K123456789");

     

}

測試的Demo


如果感興趣,可以下載Demo測試,下載2個軟件,一個是服務器軟件,一個是客戶端軟件

HslCommunicationDemo.zip

ModbusTcpServer.zip

先打開服務器,並啟動服務

技術分享圖片

再打開異形客戶端

技術分享圖片

設置好相關的參數後,啟動服務器,默認的參數如下,啟動成功的話,會彈出消息框【等待服務器的連接】

技術分享圖片

然後我們再回到服務器界面,點擊 連接異形客戶端 按鈕,彈出如下:然後將IP地址修改成本機的,端口改成剛剛在客戶端填寫的,ID和客戶端的一致

技術分享圖片

然後服務器界面彈框,連接成功。然後我們就可以回到客戶端界面進行數據讀寫的交互了。

異形Modbus客戶端 和 異形modbus服務器之間的通訊 偵聽模式的modbus-tcp客戶端通訊