KUKAVARPROXY 的 UDP 自动应答消息

目录 Content
[hide]

KUKAVARPROXY 开放了源码 https://github.com/ImtsSrl/KUKAVARPROXY ,得以查看如何应答客户端的实现部分。

一、概要

概括来说,KUKAVARPROXY启动后,会建立一个UDP对象监听 6999 端口,如果收到报文 “WHEREAREYOU?”,则会向客户端的 7000 端口发送 “KUKA|” & $MODEL_NAME[ ] & “|” & $KR_SERIALNO 的UDP报文,客户端收到后就可获取服务端的信息,包括型号、序列号,当然也可以包括服务端的 IP 地址。

二、KUKAVARPROXY 部分源码

Private Sub Form_Load()
    
    'ascolto messaggio di broadcast
    sckReceiveBroadcast.AddressFamily = AF_INET
    sckReceiveBroadcast.Binary = True
    sckReceiveBroadcast.Blocking = True
    sckReceiveBroadcast.Protocol = IPPROTO_UDP
    sckReceiveBroadcast.SocketType = SOCK_DGRAM

    sckReceiveBroadcast.Blocking = False
    sckReceiveBroadcast.LocalPort = 6999
    sckReceiveBroadcast.Broadcast = False
    'Create Socket to broadcast message
    sckReceiveBroadcast.Open

    sckSend.Protocol = IPPROTO_IP
    sckSend.SocketType = SOCK_DGRAM
    sckSend.Action = SOCKET_OPEN
    
End Sub

 

Private Sub sckReceiveBroadcast_Read(DataLength As Integer, IsUrgent As Integer)
    Dim strMess As String
    Dim cbBuffer As Integer
    Dim intError As Integer
    
    On Error GoTo errReadBroadcast
    
    'Read a recieved broadcast and display it
    cbBuffer = sckReceiveBroadcast.Read(strMess, 512)
    
    If (cbBuffer > 0) Then
        If strMess = "WHEREAREYOU?" Then
            
            sckSend.AddressFamily = AF_INET
            sckSend.Binary = True
            sckSend.Blocking = False
            sckSend.LocalPort = IPPORT_ECHO
            sckSend.RemotePort = 7000
            sckSend.HostAddress = sckReceiveBroadcast.PeerAddress
            
            If sSerialNO = "" Then
                ShowVar "$KR_SERIALNO", sSerialNO
                ShowVar "$MODEL_NAME[]", sModelName
            End If
            
            strMess = "KUKA|" & sModelName & "|" & sSerialNO
            intMess = Len(strMess)
            
            intError = sckSend.Write(strMess, intMess)
            
        End If
    End If
    
    On Error GoTo 0
    Exit Sub
    
errReadBroadcast:
    On Error GoTo 0
    
    addMessage "Errore in ReadBroadcast"
    
End Sub

三、手动测试

手动向KUKAVARPROXY 发送UDP报文,12个字节

16:41:14 DAT <--- <12> WHEREAREYOU?
[57 48 45 52 45 41 52 45 59 4F 55 3F ]

返回33个字节

16:41:16 DAT ---> [UDP] 192.168.0.103:51484 <33> KUKA|"#KR2210_2 S C4 FLR ZH210"|0
[4B 55 4B 41 7C 22 23 4B 52 32 32 31 30 5F 32 20 53 20 43 34 20 46 4C 52 20 5A 48 32 31 30 22 7C 30 ]
  • $MODEL_NAME[ ] 为 “#KR2210_2 S C4 FLR ZH210”
  • $KR_SERIALNO 为 0,因为是OfficeLite

如果频繁接收到 “WHEREAREYOU?”,KUKAVARPROXY 界面会卡顿,推测是同步处理消息导致。

四、Qt5客户端测试代码

为了简单测试,直接向KUKAVARPROXY地址 192.168.0.103:6999 发送报文。实际应用要考虑多个网卡的情况。

#include <QCoreApplication>
#include <QtNetwork>
#include <QDebug>

int main()
{
    QUdpSocket client;
    client.bind(7000);

    QByteArray msg("WHEREAREYOU?");
    client.writeDatagram(msg.data(),msg.size(),QHostAddress("192.168.0.103"),6999);

    if(client.waitForReadyRead(10000)){
        QByteArray dataRecv;
        QHostAddress ipSender;
        while(client.hasPendingDatagrams()){
            dataRecv.resize(int(client.pendingDatagramSize()));
            client.readDatagram(dataRecv.data(),dataRecv.size(),&ipSender);
        }
        QHostAddress ipSenderV4(ipSender.toIPv4Address());
        dataRecv.replace('"',"");
        dataRecv.append('|').append(ipSenderV4.toString());
        qDebug()<<dataRecv;
        QList dataRecvSplit = dataRecv.split('|');
        qDebug()<<dataRecvSplit;
    }
    return 0;
}

返回

"KUKA|#KR2210_2 S C4 FLR ZH210|0|192.168.0.103"
("KUKA", "#KR2210_2 S C4 FLR ZH210", "0", "192.168.0.103")
Press  to close this window...

五、启发

编写自己的服务端程序,可以加上自动应答功能,能向客户端提供服务端的IP地址和若干服务器信息,即实现自动发现功能。

 

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.