2011-02-04 10 views
11

Sono in procinto di iniziare a implementare alcuni protocolli di comunicazione proprietaria nel software ma non sono sicuro da dove iniziare. È il tipo di lavoro che non ho mai fatto prima e cerco aiuto in termini di risorse per approcci migliori/consigliati.Protocolli di comunicazione di implementazione in C/C++

Userò c/C++ e sono libero di usare librerie d'uso (BSD/BOOST/Apache) ma nessuna GPL. Ho usato C++ in modo estensivo, quindi usare le caratteristiche del C++ non è un problema.

Lo stack di protocollo ha tre livelli ed è già completamente specificato e verificato formalmente. Quindi tutto ciò che devo fare è implementarlo e testarlo completamente nelle lingue specificate. Dovrebbe anche menzionare che il protocollo è molto semplice ma può essere eseguito su diversi dispositivi su un affidabile livello di trasporto fisico. Conosco eventi, input, output, effetti collaterali e il comportamento delle macchine dello stato del protocollo. Generalmente, viene ricevuto un interrupt per leggere il messaggio ricevuto dal livello fisico per leggerlo e inviarlo al dispositivo in attesa. Il dispositivo ricevente può elaborare e passare il messaggio di risposta al livello del protocollo da inviare sul livello fisico.

Qualsiasi aiuto con riferimenti/raccomandazioni sarà apprezzato. Sono disposto ad usare una lingua diversa, se non altro per aiutarmi a capire come implementarle, ma dovrò ricorrere alla lingua prescelta.

Aggiornamento: Un protocollo di esempio che desidero implementare è qualcosa come SNEP.

Non devo preoccuparmi della gestione delle connessioni. Possiamo supporre la connessione è già stabilire e il protocollo non è lo scambio di dati in cui i messaggi di protocollo sono già ben definite specifiche

+1

Questa domanda è troppo generica, inizia a progettarla e implementarla e chiedi aiuto sui problemi specifici che trovi. – peoro

+1

È un compito interessante. Quando progetti la tua implementazione, tieni presente che vuoi testare ogni layer indipendentemente con i test unitari. Per ottenere un aiuto più specifico, prova a specificare da dove inizi (manipolando i pin collegati a PIO ??) e che tipo di aiuto vuoi ottenere. – harper

+0

Sono d'accordo con @peoro. Inoltre, non sono sicuro - dove stai sviluppando questo? In qualsiasi protocollo normale (su ethernet) il * OS * gestisce i livelli inferiori dello stack di rete. Utilizzi le API del sistema operativo su cui costruisci ciò che hai chiamato il livello del protocollo. Ma senza sapere dove intendi costruire questo e ciò che è specificamente problematico non posso davvero aiutarti. –

risposta

8

Inizia con interfacce e messaggi.

Dichiarare le interfacce di sessione che consentono ai peer di scambiare messaggi. Dichiara i messaggi come strutture C++ con tipi semplici, come ints, double, std :: string's ee std :: vector. Ad esempio:

// these are your protocol messages 
struct HelloRequest { 
    uint32_t seq_no; 
    // more stuff 
}; 
struct HelloResponse { 
    uint32_t seq_no; 
    // more stuff 
}; 

// Session callback for received messages 
struct SessionReceiver { 
    virtual void connected(Session*) = 0; 
    virtual void receive(Session* from, HelloRequest msg) = 0; 
    virtual void receive(Session* from, HelloResponse msg) = 0; 
    virtual void disconnected(Session*) = 0; 
}; 

// Session interface to send messages 
struct Session { 
    virtual void send(HelloRequest msg) = 0; 
    virtual void send(HelloResponse msg) = 0; 
}; 

// this connects asynchronously and then calls SessionReceiver::connected() with a newly established session 
struct SessionInitiator { 
    virtual void connect(SessionReceiver* cb, std::string peer) = 0; 
}; 

// this accepts connections asynchronously and then calls SessionReceiver::connected() with a newly accepted session 
struct SessionAcceptor { 
    virtual void listen(SessionReceiver* cb, std::string port) = 0; 
}; 

Quindi testare le interfacce codificando la logica di business che utilizza queste interfacce. Una volta che sei sicuro che le interfacce ti consentono di implementare la logica necessaria, implementa le interfacce e la serializzazione dei tuoi messaggi utilizzando il tuo framework preferito basato sugli eventi, come libevent o Boost.Asio.

Modifica: Si noti che le interfacce consentono di eseguire simulazioni o test delle implementazioni. Inoltre il fatto che la serializzazione avvenga dietro l'interfaccia significa che per i peer in-process non è necessario serializzare e deserializzare i messaggi, è possibile passarli così come sono.

+0

Mi piace questo suggerimento. Esplorerà e tornerà con domande specifiche che potrebbero sorgere. – dubnde

+0

Sta usando 'struct' per i messaggi destinati ad essere inviati tra macchine una soluzione affidabile? Per quanto ne so, ai compilatori non è richiesto di impacchettare le strutture nel modo in cui gli autori assumono spesso che saranno imballate - il padding può essere inserito per le prestazioni, ecc., Almeno quando non si usano le direttive del compilatore per istruirle diversamente. Quando l'host remoto che riceve i dati tenta di leggerlo nuovamente nella struttura, non ci sono garanzie che il layout della stessa struttura sia lo stesso lì. Sono su qualcosa qui? – amn

+1

@ amn Questi messaggi devono essere serializzati e deserializzati, ovvero non rappresentano il filo. Puoi utilizzare i buffer del protocollo google o qualsiasi altra cosa per quello. –

3

Boost.ASIO è tagliente abbastanza quando si tratta di asincrona (o sincrona) comunicazione di rete in C++

3

Dai un'occhiata allo Google Protocol Buffers.

Dalla descrizione:

buffer di protocollo sono un, efficiente, flessibile meccanismo automatico per la serializzazione dei dati strutturati - pensare XML, ma più piccolo, più veloce, e più semplice. Si definisce come si desidera strutturare i dati una volta, quindi è possibile utilizzare il codice sorgente generato speciale per scrivere e leggere facilmente i dati strutturati da e verso una varietà di flussi di dati e utilizzando una varietà di lingue.È anche possibile aggiornare la struttura dei dati senza rompere i programmi distribuiti che sono compilati rispetto al formato "vecchio".

I buffer del protocollo sono linguaggio e piattaforma neutra, quindi devono essere inclusi nel progetto. Non sono riuscito a trovare la licenza, ma almeno non dice "GPL" da nessuna parte che ho trovato.

Questo ti aiuterà con i protocolli. Con l'effettiva trasmissione dei dati, beh, a meno che tu non stia scrivendo tu stesso il sistema operativo, dovrebbero esserci alcune primitive da usare. È difficile fornire un aiuto più preciso sull'implementazione, a meno che tu non fornisca ulteriori dettagli. Per esempio, quale canale di comunicazione stai usando? Ethernet?

Ma come regola generale, si dovrebbe rendere il ISR il più breve possibile. In questi tipi di soluzioni che di solito significa copiare i dati su un buffer circolare. In questo modo non è necessario allocare memoria nell'ISR. L'ISR, dopo aver copiato i dati, dovrebbe informare i livelli superiori del pacchetto. Se puoi usare DMA, usa quello. In tal caso potrebbe essere possibile inviare la notifica prima ancora di avviare il trasferimento DMA.

Si potrebbe anche voler controllare Linux Device Drivers, chapter 10 in particolare. Controlla la parte su Bottom e Top Halves.

Problemi correlati