none
HELP per crc checksum su tcp RRS feed

  • Domanda

  • Ciao  a tutti ho un esempio in c## per il cecksum di un dato che arriva su un server tcp listener su porta 3334 

    qualcuno mi può aiutare a crearlo in visual basic questo ceck 

    word crc_SIAIP (word CRC_in, byte d)  // funzione che restituisce un intero a 16 bit senza segno e riceve come parametri un intero a 16 bit senza segno (CRC_in) e un intero a 8 bit senza segno (d)

    {

         dword i;   //dichiari variabile a 32 bit senza segno

         for (i = 0; i < 8; i++)   //ciclo for da 0 a 7 sullavariabile i

         {

              d ^= CRC_in & 1;     //d = d XOR (CTC_in AND 1)

              CRC_in >>= 1;        //CRC_in = CRC_in SHIFT_DESTRA di 1 bit

              if (d & 1)           //se d AND 1 diverso da 0

                    CRC_in ^= 0xA001;  //CRC_in = CRC_in XOR A001h

              d >>= 1;         //d = d SHIFT DESTRA di 1 bit

         }

         return CRC_in;    //ritorna come risultato CRC_in

    }

    word msg_crc_SIAIP(byte *src, dword len)   //funzione che ritorna un intero a 16 bit senza segno e riceve come parametri un puntatore a un vettore di byte chiamato src e un intero a 32 bit chiamato len

    {

         dword i;   //dichiari variabile a 32bit senza segno

         word crc_; //dichiari variabile a 16bit senza segno

         crc_ = 0;  //inizializzi la variabile a 0

         for (i = 0; i < len; i++, src++)   //fai ciclo for su viaribile i da 0 a (len – 1) incrementando ogni giro sia i che il puntatore src

              crc_ = crc_SIAIP(crc_, *src); //assegni a crc_ il risultato della funzione crc_SIAIP chiamata passando come parametric crc_ stesso e il valore puntato da src

         return crc_;  //ritorni come risultato crc_

    }

    la stringa è la seguente  : 2E0E0046"SIA-DCS"1472R000001L000001#000100[#000100|Nri1OP]_12:07:02,02-11-2020

    dovrei rispondere con questa tipo : xxxxyyyy"ACK"1472R000001L000001#000100[]

    xxxx = CRC

    yyyy = Lunghezza

    GRAZIE DI CUORE A CHI MI AIUTERA' (son in tilt)

    Paolo 

    martedì 11 febbraio 2020 11:18

Tutte le risposte

  • Ciao  a tutti ho un esempio in c## per il cecksum di un dato che arriva su un server tcp listener su porta 3334 

    qualcuno mi può aiutare a crearlo in visual basic questo ceck 

    word crc_SIAIP (word CRC_in, byte d)  // funzione che restituisce un intero a 16 bit senza segno e riceve come parametri un intero a 16 bit senza segno (CRC_in) e un intero a 8 bit senza segno (d)

    {

         dword i;   //dichiari variabile a 32 bit senza segno

         for (i = 0; i < 8; i++)   //ciclo for da 0 a 7 sullavariabile i

         {

              d ^= CRC_in & 1;     //d = d XOR (CTC_in AND 1)

              CRC_in >>= 1;        //CRC_in = CRC_in SHIFT_DESTRA di 1 bit

              if (d & 1)           //se d AND 1 diverso da 0

                    CRC_in ^= 0xA001;  //CRC_in = CRC_in XOR A001h

              d >>= 1;         //d = d SHIFT DESTRA di 1 bit

         }

         return CRC_in;    //ritorna come risultato CRC_in

    }

    word msg_crc_SIAIP(byte *src, dword len)   //funzione che ritorna un intero a 16 bit senza segno e riceve come parametri un puntatore a un vettore di byte chiamato src e un intero a 32 bit chiamato len

    {

         dword i;   //dichiari variabile a 32bit senza segno

         word crc_; //dichiari variabile a 16bit senza segno

         crc_ = 0;  //inizializzi la variabile a 0

         for (i = 0; i < len; i++, src++)   //fai ciclo for su viaribile i da 0 a (len – 1) incrementando ogni giro sia i che il puntatore src

              crc_ = crc_SIAIP(crc_, *src); //assegni a crc_ il risultato della funzione crc_SIAIP chiamata passando come parametric crc_ stesso e il valore puntato da src

         return crc_;  //ritorni come risultato crc_

    }

    la stringa è la seguente  : 2E0E0046"SIA-DCS"1472R000001L000001#000100[#000100|Nri1OP]_12:07:02,02-11-2020

    dovrei rispondere con questa tipo : xxxxyyyy"ACK"1472R000001L000001#000100[]

    xxxx = CRC

    yyyy = Lunghezza

    GRAZIE DI CUORE A CHI MI AIUTERA' (son in tilt)

    Paolo 

    Purtroppo, come contro prova, non indichi quale deve essere il crc del messaggio d'esempio. Comunque il crc in VB.Net dovrebbe essere calcolato così:

      Function crc_SIAIP(CRC_in As UInt16, d As UInt16) as UInt16
            
        For i As Integer = 0 To 7
    
          d = d Xor (CRC_in And 1)
          CRC_in = CRC_in >> 1
          If d And 1 Then CRC_in = CRC_in Xor &HA001
          d = d >> 1
    
        Next
    
        return CRC_in
                
      End Function

    mercoledì 12 febbraio 2020 11:00
  • Grazie per l'aiuto ... ecco alcune stringhe di esempio di ricezione e di risposta corrette con crc e 0LLL 

    nella risposta devo aggiungere tra apici il "ACK"    CRC = prima 4 cifre + 0 fisso + LLL = lunghezza stringa

    GRAZIE ANCORA 

    39C60046"SIA-DCS"0004R000001L000001#000100[#000100|Nri1CL]_16:11:54,02-13-2020

    573F0034"ACK"0004R000001L000001#000100[]_16:11:54,02-13-2020

    F0F0004A"SIA-DCS"0005R000001L000001#000100[#000100|Npi4001BA1]_16:11:54,02-13-2020

    C6FF0034"ACK"0005R000001L000001#000100[]_16:11:54,02-13-2020

    EA53004A"SIA-DCS"0006R000001L000001#000100[#000100|Npi4001BA3]_16:11:54,02-13-2020

    34BC0034"ACK"0006R000001L000001#000100[]_16:11:54,02-13-2020

    54C7004A"SIA-DCS"0007R000001L000001#000100[#000100|Npi4001BA6]_16:11:54,02-13-2020

    A57C0034"ACK"0007R000001L000001#000100[]_16:11:54,02-13-2020


    39C60046"SIA-DCS"0004R000001L000001#000100[#000100|Nri1CL]_16:11:54,02-13-2020

    573F0034"ACK"0004R000001L000001#000100[]_16:11:54,02-13-2020

    F0F0004A"SIA-DCS"0005R000001L000001#000100[#000100|Npi4001BA1]_16:11:54,02-13-2020

    C6FF0034"ACK"0005R000001L000001#000100[]_16:11:54,02-13-2020


    venerdì 14 febbraio 2020 16:08
  • Funziona. Se non l'hai già provato, ecco come applicarlo a tutta la stringa:

        Dim s As String = """ACK""0004R000001L000001#000100[]_16:11:54,02-13-2020"
        Dim crc As UInt16 = 0
        For i As Integer = 0 To s.Length - 1
            crc = crc_SIAIP(crc , Asc(s(i)))
        Next
        Console.WriteLine(Hex(crc))

    la funzione Asc la trovi importando Microsoft.VisualBasic. In alternativa puoi usare il metodo
    GetBytes di System.Text.Encoding

    sabato 15 febbraio 2020 08:08
  • Intanto @BlueLed ti ringrazio per il grande aiuto che  mi hai dato allego un generatore on line che ho trovato , che genera il cecksum su una stringa che vedi qui sopra è da esatta , nella generazione mia invece c'è qualcosa che non quadra.

    Ti ringrazio ulteriormente , son in debito di una mega birra , 

    

    martedì 25 febbraio 2020 09:45
  • A me il checksum di questa:

    "ACK"0005R000001L000001#000100[]_16:11:54,02-13-2020

    fornisce il valore C6FF e siccome la sua lunghezza è 52, il campo length in hex è 34.

    Quindi C6FF più 0034 più "ACK"0005R000001L000001#000100[]_16:11:54,02-13-2020 risulta:

    C6FF0034"ACK"0005R000001L000001#000100[]_16:11:54,02-13-2020

    come nel generatore online.

    Non posso sapere perchè a te non quadra dato che non so come hai usato il codice.

     

    martedì 25 febbraio 2020 11:04
  •     Data_Checksum = Chr(34) & "ACK" & Chr(34) & NumeroCom((2)) & "R" & NumeroRic((1)) & "L" & Prefis((1)) & "#" & AccountPref((1)) & "[]_" & OraEv((1)) & "," & DataEv((1))
                            LunghezzaAck = NumeroCom((2)) & "R" & NumeroRic((1)) & "L" & Prefis((1)) & "#" & AccountPref((1)) & "[]_" & OraEv((1)) & "," & DataEv((1))



                        Catch
                            ' MsgBox("MAH")

                        End Try
                        'Invio la risposta al client



                        Dim s As String = Data_Checksum  ' """ACK""0004R000001L000001#000100[]_16:11:54,02-13-2020"
                        '   If s = "" Then Exit Sub
                        Dim crc As UInt16 = 0
                        For x As Integer = 0 To s.Length - 1
                            crc = crc_SIAIP(crc, Asc(s(x)))
                        Next
                        Console.WriteLine(Hex(crc))
                        Dim LunghData As String = Len(LunghezzaAck)
                        If LunghData > 100 Then
                            LunghData = "0" & LunghData
                        Else
                            '   LunghData <99 Then
                            LunghData ="00" & LunghData
                            End If
                            TextBox1.Text += Data_Checksum & vbCrLf
                        Dim RisultatoCeck = (Hex(crc)) & LunghData & Data_Checksum
                        i = stream.Read(bytes, 0, bytes.Length)
                        Dim msg As Byte() = System.Text.Encoding.ASCII.GetBytes(RisultatoCeck)
                        stream.Write(msg, 0, msg.Length)
                        txtDebug.Text = RisultatoCeck
                    End While

                    'Chiudo la connessione
                    client.Close()

                End While

            Catch ex As SocketException

                TextBox1.Text += "SocketException: " & vbCrLf

            Finally

                server.Stop()

            End Try
        End Sub
    martedì 25 febbraio 2020 11:14
  • Puoi fare così:

    Dim Data_Checksum  as String = """ACK""0004R000001L000001#000100[]_16:11:54,02-13-2020"
    Dim crc as uint16 = 50943
                
    Dim ackmsg = String.Format("{0:x4}{1:x4}{2}", crc, Len(Data_Checksum), Data_Checksum)
                    
    Console.WriteLine(ackmsg)
    

    martedì 25 febbraio 2020 11:57
  • Grazie @BlueLed finalmente sono riuscito nel intento del checksum grazie al tuo grande aiuto ,

    MI chiedevo in Vb Net c'è un modo per mandare i comandi SYN FIN ACK , nel mio caso il FIN per dire al client che ho compreso il messaggio e non voglio che melo rispedisca ? 

    GRAZIE A TE e a chi potrà aiutarmi in merito.

     
    sabato 7 marzo 2020 14:48
  • SYN, FIN, ACK, in genere, si riferiscono a flag dei pacchetti tcp, ma tu hai già una connessione tramite socket che al suo interno gestisce il tcp/ip. Quindi se vuoi terminare la connessione basta usare il metodo Close.

    Se invece con "comandi SYN FIN ACK" intendi qualcos'altro, spiega a cosa ti riferisci.

    domenica 8 marzo 2020 12:20
  • SYN, FIN, ACK, in genere, si riferiscono a flag dei pacchetti tcp, ma tu hai già una connessione tramite socket che al suo interno gestisce il tcp/ip. Quindi se vuoi terminare la connessione basta usare il metodo Close.

    Se invece con "comandi SYN FIN ACK" intendi qualcos'altro, spiega a cosa ti riferisci.

    Ciao BlueLed , grazie

    Cerco di spiegarmi meglio, ho una stringa che arriva da una centrale , 

    E32A0044"SIA-DCS"0734R000001L000001#010101[#010101|NJP1]_14:16:02,03-09-2020

    rispondo con 
    72B20034"ACK"0734R000001L000001#010101[]_14:16:02,03-09-2020

    ho il comando close .

    Ma la centrale continua a inviare nuovamente la stringa ,si aspetta credo un FIN per chiudere e non inviare più

    nulla fino al prossimo evento.

    Se hai qualche idea in merito Grazie Ancora !!!

    

    lunedì 9 marzo 2020 17:10
  • 
    lunedì 9 marzo 2020 17:13
  • La parte del pacchetto con sfondo blu è la parte del protocollo su cui tu puoi operare. La parte precendente, tra cui SYN, FIN, ACK, etc, fa parte del protocollo TCP e serve a trasportare quei dati su cui operi. Anche se riuscissi ad inviare un FIN, l'effetto non sarebbe quello che ti aspetti. Avresti al più la conseguenza di chiudere la connessione. Se vuoi che l'altra parte non ti invii più quel messaggio devi vedere se il protocollo SIA DC-09 ti permette di farlo.

    martedì 10 marzo 2020 07:10
  • Grazie come sempre presente BlueLed,

    Analizzando a fondo con Wireshark vedo che nella comunicazione , nei vari handshake tra client e server 

    lo scambio tra esempio SEQ=80 ACK= 1 nella successiva comunicazione SEQ=1 ACK=81 e dovrebbe essere 80 perchè sia corretto mi sembra, 

    Non saprei dove inter agire per poter modificare quel ACK che è sempre su di 1 

    Grazie Mille 

     


    martedì 10 marzo 2020 10:36
  • Dato che stai lavorando in VB.Net a livello di socket, non capisco perché ti stai preoccupando dei pacchetti TCP che in tal caso vengono gestiti dal sistema. Se i pacchetti TCP/IP non li stai generando tu, non puoi metterci mano, sempre che non fai un filtro. In ogni caso non capisco cosa vuoi ottenere. Se vuoi regolare il flusso di informazioni che ricevi, dovrai ottenere e leggere il documento che contiene le specifiche del protocolo DIA DC-09 e vedere se c'è la possibilità di fare quello che hai in mente.

    martedì 10 marzo 2020 11:43
  • PROTOCOLLO SIA IP DC 9

    Il pacchetto di risposta lo sto inviando io come ACK (QUESTO ALLEGATO è CORRETTO AL CONTRARIO DEL PRECEDENTE ) da un altro ricevitore ....

    COME DOVREBBE ESSERE (QUESTO E' CORRETTO)


    martedì 10 marzo 2020 12:47
  • Può darsi che il messaggio che mandi indietro anche se corretto dal punto di vista del crc e lunghezza, non sia corretto per quanto riguarda il resto: nell'esempio che hai fatto c'è una parte tra parentesi quadre al quale rispondi con le parentesi vuote. Oppure può darsi che i messaggi successivi siano destinati ad ulteriori ricevitori.

    martedì 10 marzo 2020 16:11
  • Ciao BlueLed , grande aiuto il tuo sono riuscito in tutto quello che dovevo fare,

    mi chiedo e ho provato in tutti i modi ma non me ne vengono in mente altri con la gestione stringhe.

    il dividere in un array questa stringa :

    32D70044"SIA-DCS"1780R000001L000001#010101[#010101|NJP1]_09:05:00,03-16-2020

    ideale sarebbe 

    32D7  0044 SIA-DCS  1780 R000001 L000001 #010101 (questa parte la splitto piuttardi [#010101|NJP1] )

    09 05 00 03 16 2020   

    tipo strTem(0) = 32D7  strTemp(1) = 0044    

    * Questa stringa e dinamica cambia sempre e a volte anche le grandezze tipo da "SIA-DCS" a "NULL" 

    Come na partita a risiko 

    Grazie molte comunque dell'aiuto fino ad ora 

    Paolo

    lunedì 23 marzo 2020 17:25
  • Ciao BlueLed , grande aiuto il tuo sono riuscito in tutto quello che dovevo fare,

    mi chiedo e ho provato in tutti i modi ma non me ne vengono in mente altri con la gestione stringhe.

    il dividere in un array questa stringa :

    32D70044"SIA-DCS"1780R000001L000001#010101[#010101|NJP1]_09:05:00,03-16-2020

    ideale sarebbe 

    32D7  0044 SIA-DCS  1780 R000001 L000001 #010101 (questa parte la splitto piuttardi [#010101|NJP1] )

    09 05 00 03 16 2020   

    tipo strTem(0) = 32D7  strTemp(1) = 0044    

    * Questa stringa e dinamica cambia sempre e a volte anche le grandezze tipo da "SIA-DCS" a "NULL" 

    Come na partita a risiko 

    Grazie molte comunque dell'aiuto fino ad ora 

    Paolo

    Ho scritto questa espressione regolare in fretta e furia, probabilmente va risistemata controllando le specifiche del protocollo:

    Dim re As Regex = New Regex("^([0-9A-F]{4})(\d{4})""([^""]+)""(\d{4})(R\d{1,6})(L\d{1,6})(#\d{1,6})\[([^\]]+)\]_(.*)$")

    Una volta eseguita con

    Dim parti As Match = re.Match(messaggio)

    parti.Success dice se l'input è corretto.

    Per ottenere le parti c'è la collection parti.Groups()

    Nell'espressione ci sono nove gruppi di parentesi tonde che catturano le nove parti i cui indici nel gruppo vanno da 1 a 9.

    parti.Groups(1).Value, ad esempio, contiene il crc.

    Gli indici delle parti non hanno corrispondenza fissa se qualche parte fosse opzionale.


    • Modificato BlueLed martedì 24 marzo 2020 09:18
    martedì 24 marzo 2020 09:11
  • BluLed 5 Stelle niente politica ma grande .... tutto ok 

    Ora passo alla [#010101|NJP1]  stringa questa  e variabile [#123456|Nri1OP]  [#123456|Nri1CL] [#010101|Nri1JP1] 

    se hai qualche idea ben venga, vengo da VB6 e con VB.net 2019

    mi trovo in uno stato di non conoscenza vigile eheheh

    Grazie Ancora 


    martedì 24 marzo 2020 14:45
  • Quella è la stringa del gruppo otto, o modifichi l'espressione regolare per fargli riconoscere le due sottoparti oppure alla stringa del gruppo otto fai uno split, cercando il carattere '|'.
    martedì 24 marzo 2020 16:41
  • Ciao BlueLed ,

    Chiedo anche a te , Il timer posto nel form principale funziona solo con il button ,

    se volessi far partire il timer da un evento in entrata non si avvia , mi chiedo fa parte di Visual studio 2019 , non ricordo ci fossero questi problemi con le versioni precedenti ? 

    Tu riesci ad illuminarmi per caso.

    Grazie mille ancora 

    Paolo 


    Paolo Spagnolo

    lunedì 13 aprile 2020 14:30
  • Ciao BlueLed ,

    Chiedo anche a te , Il timer posto nel form principale funziona solo con il button ,

    se volessi far partire il timer da un evento in entrata non si avvia , mi chiedo fa parte di Visual studio 2019 , non ricordo ci fossero questi problemi con le versioni precedenti ? 

    Tu riesci ad illuminarmi per caso.

    Grazie mille ancora 

    Paolo 


    Paolo Spagnolo

    Non so in che consiste questo evento in entrata, ma se il timer sta su un form, il form deve essere stato creato per poter rispondere al timer.

    lunedì 13 aprile 2020 15:16
  • Grazie della Risposta BlueLed ,

    In pratica ad un evento nello stesso form di una situazione di allarme in entrata mi dovrebbe far partire due timer.

    Solo i Button mi attivano i Timer anche da altri form , ma in un modulo come ti metto sotto no !!!

    dall'evento :

     If StrAllarmi = "" Or StrTempAllarmi = StrAllarmi Then

                Else
                    Lb_Priority.Items.Insert(0, StrAllarmi)
                    ' Lb_Priority.Items.Add()
                    StrTempAllarmi = StrAllarmi

                    Module1.Start01()
                    Module1.Start02()
                    StrAllarmi = ""
                    StrEventi = ""
                End If

    al modulo1 :

    Modulo 1  'Ricevitore è il form dove sono inseriti i Timer 

      Public Function Start01()

            Ricevitore.Timer_Allarme.Interval = 500
            Ricevitore.Timer_Allarme.Start()
            Ricevitore.Gif_Alarm.Visible = True
            For Idx = 1 To 5 ' <<<<<<<<< da 1 a 5
                Ricevitore.Controls("Label" & Idx.ToString).Visible = Not Ricevitore.Controls("Label" & Idx.ToString).Visible

                '   Me.Controls("Panel" & i.ToString).Visible = Not Me.Controls("Panel" & i).Visible
            Next
        End Function
        Public Function Start02()

            Ricevitore.Timer_Suoni.Interval = 2000
            Ricevitore.Timer_Suoni.Start()
            If Ricevitore.CheckBox1.Checked = False Then
                Ricevitore.Timer_Suoni.Stop()


            Else
                Ricevitore.Timer_Suoni.Start()
                'Dim sPath = Application.StartupPath & "\Data\Config\"
                'My.Computer.Audio.Play(sPath & "priorita4.wav")
            End If
        End Function


    Paolo Spagnolo


    lunedì 13 aprile 2020 15:58
  • Dato che il topic è lo stesso di un altro che hai aperto, rispondo lì per evitare l'off topic.
    lunedì 13 aprile 2020 16:39