Domanda

Supponi di avere una variabile contatore sul lato client. Quando invio una richiesta al server, invio il valore di questa variabile, quindi lo incremento di uno (per la richiesta successiva al server). Il server tiene traccia di questo contatore in modo indipendente e verifica che il conteggio inviato dal client sia 1 in più rispetto alla sua copia (lato server) del conteggio. Va tutto bene e dandy, ma considera la seguente situazione:

  1. Il client invia, diciamo, 23 al server.
  2. Il server riceve 23, lo convalida e incrementa il proprio contatore a 23.
  3. Il server restituisce il codice All-Okay al client

-ma -

Lungo la strada dal server al client, il codice di ritorno viene danneggiato. Il client ritiene quindi che il server non abbia aggiornato il proprio contatore e quindi lascia il contatore sul lato client a 23. Da questo punto in poi, il client e il server non sono sincronizzati.

Qualcuno conosce schemi robusti che funzionerebbero di fronte a possibili corruzioni / errori?

Grazie,
Cameron

È stato utile?

Soluzione

Invece di usare un contatore che aumenta linearmente, puoi usare un "nonce" casuale valore di ben 64 bit di entropia o più. Quando il server riceve una richiesta dal client, il server verifica se il nonce corrisponde all'ultima che ha inviato al client. In tal caso, la richiesta viene elaborata e il server genera un nuovo valore nonce casuale per inviare la risposta.

Il server può conservare gli ultimi due valori nonce da inviare al client. Se il client invia il vecchio valore, il server presume che il messaggio più recente al client potrebbe essere andato perso.

Il metodo sopra presuppone che l'obiettivo sia impedire a due client diversi di utilizzare le stesse credenziali per comunicare con il server. Il vantaggio di usare il metodo nonce è che il prossimo valore non può essere facilmente previsto.

Altri suggerimenti

La risposta semplice è rendere uno dei client o dei server il proprietario della risorsa, invece di creare entrambi la propria copia della risorsa.

Se stai usando un protocollo affidabile come TCP, non devi preoccuparti che il messaggio non arrivi al client.

Una buona cosa da seguire quando si fa funzionare client / server è rendere tutte le operazioni idempotenti. Ciò significa che ogni funzione può essere chiamata una o più volte senza effetti collaterali. In questo caso non avresti affatto una funzione di "incremento". Invece avresti una funzione 'set'.

Che ne dici di non avere il client che aggiorna la sua copia locale fino a quando il server non riconosce l'aggiornamento del contatore del server.

Il client calcola il valore successivo Il client invia il valore successivo al server Il server verifica che il valore successivo sia valido (non già visto) Il server aggiorna il contatore al valore successivo (se necessario) Il server notifica al client che è stato ricevuto il valore successivo Il client aggiorna il contatore locale al valore successivo

Se il server non riceve l'aggiornamento client, il client rinvia semplicemente il valore successivo calcolato. Se il client non riceve la conferma del valore successivo, invierà nuovamente il valore successivo, ma il server che lo ha già visto non si aggiorna, ma semplicemente riconosce. Alla fine, il client vede il messaggio del server e continua. Questo riguarda il caso di messaggi persi.

Se sei preoccupato per la corruzione, calcola un checksum sul messaggio e invia anche quello. Ricalcola il checksum alla ricezione e confrontalo con quello inviato. Generalmente lo stack di rete fa questo per te, quindi non mi preoccuperei troppo a meno che tu non stia eseguendo il tuo protocollo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top