2009-07-31 12 views
5

Sto provando a scrivere un'app che scambia dati con altri iPhone che eseguono l'app attraverso il framework di Game Kit. Gli iPhone si scoprono e si connettono bene, ma i problemi si verificano quando invio i dati. So che gli iPhone sono collegati correttamente perché quando serializzo una NSString e la mando attraverso la connessione, esce dall'altra parte. Ma quando provo ad archiviare un oggetto più grande (usando NSKeyedArchiver) ottengo il messaggio di errore "AGPSessionBroadcast fallito (801c0001)".iPhone: invio di dati di grandi dimensioni con Game Kit

Suppongo che ciò avvenga perché i dati che sto inviando sono troppo grandi (i miei file hanno dimensioni di circa 500k, Apple sembra raccomandare un massimo di 95k). Ho provato a suddividere i dati in diversi trasferimenti, ma non riesco mai a farlo scomparire correttamente all'altra estremità. Mi chiedo se qualcun altro si è scontrato con questo problema e come lo hai risolto.

risposta

4

Ho avuto lo stesso problema con i file di circa 300K. Il problema è che il mittente deve sapere quando il ricevitore ha svuotato il tubo prima di inviare il blocco successivo.

Ho finito con un semplice motore di stato che funzionava su entrambi i lati. Il mittente trasmette un'intestazione con quanti byte totali saranno inviati e la dimensione del pacchetto, quindi attende il riconoscimento dall'altra parte. Una volta ottenuto l'handshake, invia pacchetti di dimensione fissa, ciascuno contrassegnato con un numero di sequenza.

Il ricevitore riceve ciascuno, lo legge e lo aggiunge a un buffer, quindi scrive di nuovo sulla pipe che ha ottenuto il pacchetto con la sequenza #. Il mittente legge il pacchetto #, elimina il valore di un altro buffer, e così via e così via. Ogni lato tiene traccia dello stato in cui si trovano (inattivo, invio intestazione, ricezione intestazione, invio dati, ricezione dati, errore, fatto ecc.) Le due parti devono tenere traccia di quando leggere/scrivere l'ultimo frammento poiché è probabilmente inferiore alla dimensione del buffer completo.

Questo funziona bene (anche se un po 'lento) e può scalare in qualsiasi dimensione. Ho iniziato con le dimensioni del pacchetto 5K, ma ha funzionato piuttosto lentamente. L'ho spinto a 10K ma ha iniziato a causare problemi, quindi ho fatto marcia indietro e l'ho tenuto su 8096. Funziona bene sia per i dati binari che di testo.

+0

Ciao Ramin, puoi condividere alcuni snippet di codice relativi alla soluzione che hai suggerito. – Anshul

3

Tenere presente che GameKit non è un'API di trasferimento file generale; è più inteso per gli aggiornamenti di dove si trova il giocatore, quale sia la posizione corrente o altri oggetti ecc. Quindi inviare 300k per un gioco non sembra ragionevole, anche se posso capire il dirottamento dell'API per i meccanismi di condivisione generale.

Il problema è che non è una connessione TCP; è più una connessione UDP (datagramma). In questi casi, i dati non sono uno stream (che viene impacchettato dal TCP) ma piuttosto una gigantesca quantità di dati. (Tecnicamente, UDP può essere frammentato in più pacchetti IP, ma perde uno di questi e l'intero UDP viene perso, al contrario di TCP, che riproverà).

L'MTU per la maggior parte delle reti cablate è ~ 1.5k; per il bluetooth, è intorno a ~ 0.5k. Quindi qualsiasi pacchetto UDP che hai inviato (a) può perdersi, (b) può essere diviso in più pacchetti IP di dimensioni MTU, e (c) se uno di questi pacchetti viene perso, allora perderai automaticamente l'intero set.

La tua strategia migliore è emulare TCP - invia pacchetti con un numero di sequenza. L'estremità ricevente può quindi richiedere trasmissioni dupe di pacchetti che sono andati persi in seguito. Se stai utilizzando l'equivalente di un NSKeyedArchiver, allora un suggerimento è quello di scorrere le chiavi e scriverle come chiavi individuali (supponendo che ciascun valore con chiave non sia così grande da solo). Avrai bisogno di avere un qualche tipo di ACK per ogni pacchetto che viene inviato indietro, e un ACK totale quando hai finito, così il mittente sa che è OK per eliminare i dati dalla memoria.

Problemi correlati