Invio immediato pacchetto tcp, TncTCPServer

di il
9 risposte

Invio immediato pacchetto tcp, TncTCPServer

Ciao ragazzi,

sto usando i componenti TncTCPServer, per fare appunto un server tcp che mandi e ricevi dei pacchetti ai client collegati.

il server è fatto in delphi mentre i client no, credo in .net.

il fatto è che sull evento onreceive del componente TncTCPServer io mi aspetto dei pacchetti da 25 byte, mentre spesso

e volentieri sono piu grossi, quindi vengono accodati piu messaggi.

Non esiste un modo per far in modo che riceva un evento per ogni messaggio?, da 25 byte appunto.

Ho fatto una prova anche in delphi usando come client il componente standard i delphi TClientSocket e facendo un ciclo che manda per esempio 100 messaggi da 1 byte, sull evento onreceive del server si scatenano, ad esempio, solo 2 eventi con messaggi da 50 byte.

io vorrei che ad ogni send del client, corrisponda un evento onreceive sul server, è possibile?

9 Risposte

  • Re: Invio immediato pacchetto tcp, TncTCPServer

    No, è il funzionamento del TCP. Dovrai provvedere tu ad individuare i singoli gruppi di dati che devi elaborare di volta in volta.

  • Re: Invio immediato pacchetto tcp, TncTCPServer

    Grazie oregon, ma perlomeno arrivano a multipli?, cioe avendo il paccketto da 25 byte ricevo multipli di 25 o possono arrivare anche “pezzi” di pacchetti?  esempio 110 byte? quindi 4 pacchetti e “ un tot” ?

  • Re: Invio immediato pacchetto tcp, TncTCPServer

    Possono arrivare anche ‘pezzi’ : come suddividere la sequenza di byte inviati su un canale tcp e' indipendente dalla dimensione dei singoli pacchetti inviati (che potrebbero avere QUALUNQUE dimensione) .

    Quando invii qualcosa su tcp gli approcci sono

    1. apri la connessione, invii tutto, chiudi la connessione. Buono per grandi quantità di dati
    2. apri la connessione, invii molti ‘messaggi’, ognuno con la sua ‘dimensione’., chiudi la connessione. Buono per invio/ricezione di blocchetti di dati
  • Re: Invio immediato pacchetto tcp, TncTCPServer

    08/04/2024 - ziobacco ha scritto:


    Non esiste un modo per far in modo che riceva un evento per ogni messaggio?, da 25 byte appunto.

    Devi usare un “terminatore” concordato tra il server e il client per spezzare logicamente i dati che arrivano e generare i messaggi corrispondenti ai dati che progressivamente entrano nel socket.

  • Re: Invio immediato pacchetto tcp, TncTCPServer

    No ziobacco i dati possono essere consegnati in qualsiasi quantità. Sono rispettarispettate la consegna senza errori e in ordine. Il TCP non sa nulla del pacchetto applicafivo gestito da te ma gestisce solo un flusso di byte che consegna nell'ordine di invio ma non nella quantità e nel tempo che vuoi tu.

    Quindi, come indicato, usa una sequenza (o un carattere) terminatore a te noto che indica la fine dei dari che ti servono. Implementa una ‘macchina a stati’ e gestisci i tuoi pacchetti

  • Re: Invio immediato pacchetto tcp, TncTCPServer

    In realtà non abbiamo un terminatore, ma un inizio, cioè i messaggi che arrivano dai client
    devono iniziare con la parola "MSG1="e poi sono lunghi appunto 25 bytes.

    quindi riassumendo mi servirebbe una lista di bytes, uno per ogni client connesso, dove memorizzo gli eventuali pezzi di pacchetti incompleti;
    Nell evento di ricezione del dato controllo se ho "MSG1="e prendo fino al successivo "MSG1="  (se esiste), ciclando quindi fino a che ho pezzi da 25 bytes, se ho pezzi piu corti significa che è un pacchetto incompleto e lo memorizzo
    per poi metterlo all inizio dei dati ricevuti in un secondo evento,

    una cosa cosi'?

    
    procedure TfrmMain.TCPServerReadData(Sender: TObject; aLine: TncLine;
     const aBuf: TArray<System.Byte>; aBufCount: Integer);
    VAR
     lastbytes:TBytes;
     MsgArray: TBytes;
     msg,Singlemsg,S:string;  
    begin
     IncompletePackets.TryGetValue(ALINE,lastbytes);//IncompletePackets= dictionary contenente tncline e tbytes
     msgarray := Copy(aBuf, 0, aBufCount);
    
     msg:=StringOf(MsgArray);
     if Length(lastbytes) > 0 then
     begin
       msg:=StringOf(lastbytes)+msg;
       lastbytes:=[];    
     end;
     while  Pos(cMsgHeader1,MSG)>0 do
     begin
       msg:= Copy(msg,Pos(cMsgHeader1,MSG)+8,Length(msg)-8);
       if Pos(cMsgHeader1,msg)>0 then
       begin
         Singlemsg:=Copy(msg,0,Pos(cMsgHeader1,msg)-1);
       end else
       begin
         singlemsg:=msg;
       end;
       S:=cMsgHeader1+Singlemsg;
       MsgArray:=BytesOf(S);
       if Length(MsgArray)<25 then
       begin
         lastbytes:= MsgArray;
       end
       else
       begin
     //    MsgArray// ho il mio messaggio di 25 bytes 
       end;
     end;
    end;
    
  • Re: Invio immediato pacchetto tcp, TncTCPServer

    08/04/2024 - ziobacco ha scritto:


    n realtà non abbiamo un terminatore, ma un inizio, cioè i messaggi che arrivano dai client
    devono iniziare con la parola "MSG1="e poi sono lunghi appunto 25 bytes.

    Magari la scelta dipende da altre motivazioni, ma la butto lì: con tutti i protocolli standard che ci sono (Web API REST, Web Service, gRPC, ecc.), dato che stai inviando un pacchetto formato sostanzialmente da testo, perché non utilizzare quelli al posto del socket a basso livello.

    A meno che non vi siano questioni di performance assolutamente imprescindibili, o la necessità di comunicare con hardware specifico, l'apertura e la gestione di un socket sarebbe l'ultima soluzione a cui farei ricorso in uno generico scenario di comunicazione tra processi.

    Il tuo codice tra l'altro usa dei “buffer” al posto di più comodi “stream”, che sono senz'altro più gestibili a livello di API e consentono di scrivere codice più leggibile.

  • Re: Invio immediato pacchetto tcp, TncTCPServer

    ZeroMQ e' una bella libreria che semplifica molto le comunicazioni su rete, supportando in modo semplice diversi ‘paradigmi'

    E' stata creata per applicazioni HPC (High Performance Computing) come alternativa a MPI (Message Passing Interface), ma puo' essere usata anche per applicazioni piccoline.

    https://zeromq.org/

    Esiste ANCHE per Delphi.

    E' molto compatta (come tutte le librerie ‘intelligenti’ ;-) ) e ti risolve il problema del tcp: spedisci un ‘messaggio’, ricevi un 'messaggio', con QUALUNQUE protocollo (tcp/udp/…).

  • Re: Invio immediato pacchetto tcp, TncTCPServer

    08/04/2024 - migliorabile ha scritto:


    ZeroMQ e' una bella libreria che semplifica molto le comunicazioni su rete, supportando in modo semplice diversi ‘paradigmi'

    Non volevo “esagerare”, ma effettivamente questi tool sono troppo comodi ed efficaci per non essere presi in considerazione. :)

    Oltre a ZeroMQ si può usare anche RabbitMQ (c'è un driver STOMP per Delphi) o il recente NATS (qui il client).

    Assieme alla comodità dei pacchetti e del colloqui, c'è il discorso di affidabilità, persistenza e tanti altri vantaggi…

Devi accedere o registrarti per scrivere nel forum
9 risposte