Получите длину содержимого из первых двух байтов модифицированного Java UTF (созданного с использованием метода java writeUTF()) в swift

Я использую GCDAsyncSocket для создания TCP-клиента на iOS (используя swift). Клиент взаимодействует с TCP-сервером, написанным на JAVA. Данные записываются в сокет с помощью метода JAVA writeUtf(). Итак, чтобы прочитать данные на TCP-клиенте, мне нужно знать длину данных, доступных в сокете. Формат java UTF отличается от стандартного UTF и кодирует длину содержимого в первых 2 байтах данных. Длина входящих данных должна быть известна для чтения данных в GCDAsyncSocket.

Вопросы:

  1. Как получить размер входящих данных из первых двух байт модифицированного UTF-8 в swift?

  2. Есть ли лучший способ прочитать данные из java writeUTF(), обнаружив конец потока?


person Suraj    schedule 27.09.2017    source источник
comment
Лучше всего, вероятно, портировать java.io.DataInputStream.readUTF().   -  person teppic    schedule 27.09.2017
comment
Другое большое отличие состоит в том, что \000 кодируется как \700\600.   -  person Johannes Kuhn    schedule 26.04.2020


Ответы (1)


Я использовал свою собственную функцию getJavaUTFFrom для чтения utf из tcp-сокета java-сервера. во-первых, вы должны получить данные из сокета tcp в NSMutableData и преобразовать его содержимое в строку с помощью getJavaUTFFrom.

@discardableResult func getJavaUTFFrom(_ data: NSMutableData, location: Int, toStr: inout String)->Int! {

    var utfLength: Int = 0

    //getJavaCharFrom reads utf string length
    getJavaCharFrom(data, location: location, toIntVar: &utfLength)


    if location + utfLength - 1 > data.length {
        print("out of message body range getJavaUTFFrom at location: \(location)")

        return nil 

    }


    var buff = [UInt8](repeating: 0, count: Int(utfLength))
    data.getBytes(&buff, range: NSRange(location: location+MemoryLayout<UInt16>.size, length: Int(utfLength)))
    toStr = String(bytes: buff, encoding: String.Encoding.utf8)!
    return location + MemoryLayout<UInt16>.size + utfLength //returning java modified utf8 string length
}

@discardableResult func getJavaCharFrom(_ data: NSMutableData, location: Int, toIntVar: inout Int)->Int! {

    if location + MemoryLayout<UInt16>.size-1 > data.length {
        print("out of message body range getJavaCharFrom")
        return nil
    }

    var tmp = UInt16(0)
    data.getBytes(&tmp, range: NSRange(location: location, length: MemoryLayout<UInt16>.size))
    toIntVar=Int(tmp.bigEndian)
    return location + MemoryLayout<UInt16>.size
}
person NMaks    schedule 26.04.2020