es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo dividir los datos en paquetes y enviarlos utilizando una conexión UDP.

Estoy tratando de enviar una imagen a través de una conexión UDP.

class Connect: NSObject {
    var connection: NWConnection?

    func connectToUDP(host: String, port: UInt16) {
        let host = NWEndpoint.Host(host)
        guard let port = NWEndpoint.Port(rawValue: port) else { return }
        let messageToUDP = "Bonjour"

        connection = NWConnection(host: host, port: port, using: .udp)

        connection?.stateUpdateHandler = { (newState) in
            print("This is stateUpdateHandler:")
            switch (newState) {
            case .ready:
                print("State: Ready\n")
                self.sendUDP(messageToUDP)
                self.receiveUDP()
            default:
                print("ERROR! State not defined!\n")
            }
        }
        connection?.start(queue: .global())
    }

    func sendUDP(_ content: Data) {
        connection?.send(content: content, completion: NWConnection.SendCompletion.contentProcessed(({ (NWError) in
            if (NWError == nil) {
                print("Data was sent to UDP")
            } else {
                print("ERROR! Error when data (Type: Data) sending. NWError: \n \(NWError!)")
            }
        })))
    }
   }

Convertí la imagen en datos y cuando lo envío:

guard let image = UIGraphicsGetImageFromCurrentImageContext(),
let data = image.pngData() else { return }
connect.connectToUDP(host: "192.168.XX.XX", port: 10000)
connect.sendUDP(data)

Obtuve este error:

ERROR! Error when data (Type: Data) sending. NWError: POSIXErrorCode: Message too long

¿Cómo puedo dividir los datos en paquetes y asegurar que se reconstruyan completamente en el receptor?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para dividir los datos en paquetes para la transmisión UDP, puedes usar una técnica llamada fragmentación de paquetes. Esto implica dividir los datos en fragmentos más pequeños, o paquetes, que luego pueden ser enviados individualmente a través de la red y reensamblados por el receptor.

    Una forma de implementar la fragmentación de paquetes es definir un tamaño máximo de paquete, y luego dividir los datos en múltiples paquetes de ese tamaño o más pequeños. Puedes usar la función stride para crear una secuencia de desplazamientos en los datos, y luego usar el método subdata(in:) de Data para obtener trozos de datos para cada paquete.

    Aquí tienes un ejemplo de cómo podrías modificar la función sendUDP para usar la fragmentación de paquetes:

    func sendUDP(_ content: Data) {
        let maxPacketSize = 1024 // ajusta esto según tus necesidades
        let packets = stride(from: 0, to: content.count, by: maxPacketSize).map {
            content.subdata(in: $0..<min($0+maxpacketsize, content.count))
        }
    
        for packet in packets {
            connection?.send(content: packet, completion: nwconnection.sendcompletion.contentprocessed(({ (nwerror) in
                if (nwerror == nil) {
                    print("paquete enviado por udp")
                } else {
                    print("¡error! error al enviar el paquete. nwerror: \n \(nwerror!)")
                }
            })))
        }
    }
    

    esta función divide los datos en paquetes de tamaño maxpacketsize (por defecto, 1024), crea un bucle para iterar sobre cada paquete y enviarlo usando el método connection?.send. el manejador de finalización muestra cualquier error encontrado durante el envío.

    ten en cuenta que el receptor deberá conocer el tamaño de los paquetes para poder volver a ensamblar correctamente los datos. puedes incluir el tamaño del paquete como una cabecera en cada paquete, o acordar un tamaño de paquete fijo a nivel de protocolo. content.count))=”” }=”” for=”” packet=”” in=”” packets=”” {=”” connection?.send(content:=”” packet,=”” completion:=”” nwconnection.sendcompletion.contentprocessed(({=”” (nwerror)=”” in=”” if=”” (nwerror=”=” nil)=”” {=”” print(“paquete=”” enviado=”” por=”” udp”)=”” }=”” else=”” {=”” print(“¡error!=”” error=”” al=”” enviar=”” el=”” paquete.=”” nwerror:=”” \n=”” (nwerror!)”)=”” }=”” })))=”” }=”” }=”” “`=”” esta=”” función=”” divide=”” los=”” datos=”” en=”” paquetes=”” de=”” tamaño=”” maxpacketsize=”” (por=”” defecto,=”” 1024),=”” crea=”” un=”” bucle=”” para=”” iterar=”” sobre=”” cada=”” paquete=”” y=”” enviarlo=”” usando=”” el=”” método=”” connection?.send.=”” el=”” manejador=”” de=”” finalización=”” muestra=”” cualquier=”” error=”” encontrado=”” durante=”” el=”” envío.=”” ten=”” en=”” cuenta=”” que=”” el=”” receptor=”” deberá=”” conocer=”” el=”” tamaño=”” de=”” los=”” paquetes=”” para=”” poder=”” volver=”” a=”” ensamblar=”” correctamente=”” los=”” datos.=”” puedes=”” incluir=”” el=”” tamaño=”” del=”” paquete=”” como=”” una=”” cabecera=”” en=”” cada=”” paquete,=”” o=”” acordar=”” un=”” tamaño=”” de=”” paquete=”” fijo=”” a=”” nivel=”” de=””></min($0+maxpacketsize, content.count))
    }

    for packet in packets {
        connection?.send(content: packet, completion: nwconnection.sendcompletion.contentprocessed(({ (nwerror) in
            if (nwerror == nil) {
                print("paquete enviado por udp")
            } else {
                print("¡error! error al enviar el paquete. nwerror: \n \(nwerror!)")
            }
        })))
    }
    

    }
    “`

    esta función divide los datos en paquetes de tamaño maxpacketsize (por defecto, 1024), crea un bucle para iterar sobre cada paquete y enviarlo usando el método connection?.send. el manejador de finalización muestra cualquier error encontrado durante el envío.

    ten en cuenta que el receptor deberá conocer el tamaño de los paquetes para poder volver a ensamblar correctamente los datos. puedes incluir el tamaño del paquete como una cabecera en cada paquete, o acordar un tamaño de paquete fijo a nivel de protocolo.>

Comments are closed.