swift inputstream nsstream

Recibiendo datos de NSInputStream en Swift



nsstream (2)

Intento enviar y recibir datos con NSOutputStream y NSInputStream en Swift. El envío de datos está funcionando bien, pero tengo algunas preguntas sobre la recepción.

Encontré una solución con el manejo de NSStreamEvent, que he probado.

En primer lugar mi función para inicializar la conexión:

func initNetworkCommunication(){ var host : CFString = "127.0.0.1" var port : UInt32 = 7001 var readstream : Unmanaged<CFReadStream>? var writestream : Unmanaged<CFWriteStream>? CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, host, port, &readstream, &writestream) inputstream = readstream!.takeRetainedValue() outputstream = writestream!.takeRetainedValue() inputstream.delegate = self outputstream.delegate = self inputstream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) outputstream.scheduleInRunLoop(NSRunLoop.currentRunLoop(), forMode: NSDefaultRunLoopMode) inputstream.open() outputstream.open() }

Esta parte está funcionando. He establecido a los delegados en auto, por lo que debería ser capaz de manejar los NSStreamEvents en esta clase.

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { switch (eventCode){ case NSStreamEvent.OpenCompleted: NSLog("Stream opened") break case NSStreamEvent.HasBytesAvailable: NSLog("HasBytesAvailable") break case NSStreamEvent.ErrorOccurred: NSLog("ErrorOccurred") break case NSStreamEvent.EndEncountered: NSLog("EndEncountered") break default: NSLog("unknown.") } }

A mi entender, cada vez que llegan datos, debería imprimir "HasBytesAvaible", pero se imprimió "desconocido". cada vez. Así que jugué un poco y funcionó con esto:

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { var buffer = [UInt8](count: 4096, repeatedValue: 0) while (inputstream.hasBytesAvailable){ let result: Int = inputstream.read(&buffer, maxLength: buffer.count) } switch (eventCode){ case NSStreamEvent.OpenCompleted: NSLog("Stream opened") break case NSStreamEvent.HasBytesAvailable: NSLog("HasBytesAvailable") var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding) NSLog("output: %@", output) receiveMessage(output) //only adds the message to an array break case NSStreamEvent.ErrorOccurred: NSLog("ErrorOccurred") break case NSStreamEvent.EndEncountered: NSLog("EndEncountered") break default: NSLog("unknown.") } }

¿Está funcionando de esta manera, pero quería preguntarte si esta es la forma correcta? ¿Cuál es la mejor práctica en este punto?

ACTUALIZACIÓN Trabajé en ello nuevamente hace unas semanas y descubrí mis errores. Así que aquí está el código de trabajo.

func stream(aStream: NSStream, handleEvent eventCode: NSStreamEvent) { switch (eventCode){ case NSStreamEvent.ErrorOccurred: NSLog("ErrorOccurred") break case NSStreamEvent.EndEncountered: NSLog("EndEncountered") break case NSStreamEvent.None: NSLog("None") break case NSStreamEvent.HasBytesAvailable: NSLog("HasBytesAvaible") var buffer = [UInt8](count: 4096, repeatedValue: 0) if ( aStream == inputstream){ while (inputstream.hasBytesAvailable){ var len = inputstream.read(&buffer, maxLength: buffer.count) if(len > 0){ var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding) if (output != ""){ NSLog("server said: %@", output!) } } } } break case NSStreamEvent.allZeros: NSLog("allZeros") break case NSStreamEvent.OpenCompleted: NSLog("OpenCompleted") break case NSStreamEvent.HasSpaceAvailable: NSLog("HasSpaceAvailable") break }


Estoy usando el código escrito por Hoedding, y noté un error. La línea:

var output = NSString(bytes: &buffer, length: buffer.count, encoding: NSUTF8StringEncoding)

debe ser reemplazado por:

var output = NSString(bytes: &buffer, length: len, encoding: NSUTF8StringEncoding)

Debe ingresar en la var de output solo el número de caracteres devueltos por el servidor, y no la longitud completa del búfer, o obtendrá basura de solicitudes anteriores.


Te estás perdiendo el evento hasSpaceAvailable , que espero que ocurra cuando dice "desconocido". Te está diciendo que está listo para recibir más datos.

En general, evito usar valores default en las declaraciones de cambio para las enumeraciones, ya que el compilador te dirá cuándo te has perdido algo.