Red de conocimiento informático - Material del sitio web - Cómo separar paquetes cuando se utiliza GCDASyncSocket

Cómo separar paquetes cuando se utiliza GCDASyncSocket

Solución 1:

No entiendes bien el papel del objetivo. GCDAsyncSocket (como su nombre indica) es un socket asíncrono. Esta etiqueta puede ayudarle a relacionar los datos recibidos con los pedidos recibidos y enviar pedidos enviados a personas exitosas.

Por ejemplo, si desea enviar datos en un futuro cercano, siga la etiqueta -1: taga (o algo así). similar) para enviar alguna secuencia a su socket. Probablemente no ahora. Luego puede enviar inmediatamente otro mensaje al siguiente pedido, diciendo mensajeB y etiquetaB. Ya sabes, el mensaje A realmente se envía, puedes notificar al socket: un socket escribe datos con la etiqueta: atag. Aquí, si se envía el mensaje A, es el valor de una etiqueta etiqueta A, si se envía el mensaje B, es el valor de la etiqueta B. La etiqueta no envía un mensaje; simplemente le ayuda a confirmar su pedido.

Lo mismo ocurre en el extremo receptor. La orden que usted da recibe algunos datos y asigna una etiqueta a esta orden en particular. Una vez que reciba los datos, notifique (a través de socket: didredata: with tag:) que la secuencia de etiquetas que desea conocer fue exitosa.

Puedes utilizar cierta información semántica de la etiqueta y ponerla en tu mensaje. Pero incluso entonces, los pedidos se recibieron en la marca de la notificación, pero uno de los pedidos nunca fue enviado. Si desea utilizar etiquetas colocadas en el mensaje del receptor, primero debe recibir (al menos parte) del mensaje y analizarlo.

Volviendo al meollo de la cuestión: básicamente tienes dos posibilidades, y conocer el tipo de datos que llegan:

Saber el orden en el que se envían los datos es muy similar al orden en el que se reciben los datos.

Utiliza encabezados con tipos de datos reconocidos. Recibir solo los encabezados y recibir y analizar el resto del mensaje depende de los datos del encabezado.

Editar

El siguiente es un ejemplo del segundo método. Supongamos que puede enviar varios objetos de clase A, clase B, etc.

El tipo y tamaño de los datos, que pueden incluir encabezados:

estructura typedef {

NSUInteger tipo _ id

nsu tamaño entero;

} header_t;

#define typeIdA 1

#define typeIdB 2

// ...

Una vez que quieras enviar Objeto obj y objKey:

NSMutableData * data =[NSMutableData data];

nskeydarchiver * Archiver =[[nskeydarchiver alloc]initforwritingtwithmatabledata:data];

[ Objeto de codificación del archivador:obj forKey:obj key];

header_t header;

if ([obj class] == [A class]) {

head .type _ id = typeIdA

} else if ([obj class] == [clase B]) {

head.type _ id = typeIdB

} De lo contrario...

// ....

tamaño del encabezado = longitud de los datos;

datos ns * datos del encabezado =[datos ns conBytes :&Longitud del encabezado:sizeof(header)];

Número de bytes de datos: longitud:

encabezado = NSData.length

[async socket writeData: datos de cabeza con tiempo de espera:-1 etiqueta:etiqueta de cabeza];

[async socket writeData:datos con tiempo de espera:-1 etiqueta:etiqueta de datos];

Si lo desea , puede recibir una notificación de entrega exitosa o error, pero omita ese paso aquí.

En el receptor, espera un encabezado por primera vez:

[receive socket readDataToLength:sizeof(header _ t)with time out:-1 tag:rcvHdrTag];

/ /rcvHdrTag no puede coincidir con una de las etiquetas typeIdX

En su socket: didredata:con etiqueta: ¿desea distinguir su encabezado o aún (recibido o comenzando aquí!)

-( void)socket:(GCDAsyncSocket *)como el socket leyó los datos:(ns data *)datos con etiqueta:(long)tag {

header_t header;

id obj

clave de identificación;

interruptor (etiqueta) {

Caso rcvHdrTag:

[Número de bytes de datos: & amp longitud del encabezado: tamaño de (encabezado )];

//Ahora ya sabes qué aceptar

[como ocket readDataToLength:header . size with time out:-1 tag:header type];

Return;

Romper; //Lo sé, redundante :-)

IdA del tipo de caso:

objKey = objKeyA// Sea lo que sea. ..

Pausa;

Tipo de caso IdB:

objKey = objKeyB

// ....

}

nskeydunarchiver * un Archiver =[[nskeydunarchiver alloc]initForReadingWithData:data];

obj =[unarchiver decodeObjectForKey:obj key];

/ /Almacena tus objetos...

}

Este no es el ejemplo más elegante, ignora el árbol de objetos y las dependencias entre objetos en el archivo, pero debes saberlo.