使用GCDAsyncSocket传输文件接收器

时间:2014-08-23 09:25:38

标签: ios objective-c sockets swift gcdasyncsocket

我正在使用GCDAsyncSocket。编写一个用于在两个设备之间传输文件的应用程序,在接收文件时会遇到一些问题: 当我想将大约60 KB的文本文件发送到另一个接收设备(iOS设备或iOS模拟器)时,需要在数据之前添加一些数据包信息,如下所示:

2字节标题版本, 1个字节标识数据或命令, 4字节数据大小, 保留空间为25个字节,

32个字节后是文件数据,文本文件或图像文件或其他文件。 所以,在我调用socket.writeData之前,我写了一个NSMutableData,然后发送到接收设备。

    var sendData: NSMutableData = NSMutableData()
    var fileData: NSData = NSData(contentsOfFile: "file path", options: NSDataReadingOptions.DataReadingMapped, error: &error)

    // TCP_HEADER_VERSION is Int16, value is 1
    var headerVersion = TCP_HEADER_VERSION.bigEndian
    var unPackVersionData: NSData = NSData(bytes: &headerVersion, length: 2)
    sendData.appendData(unPackVersionData)

    // dataType is Int, value is 0
    var dataTypeTemp = dataType
    sendData.appendData(NSData(bytes: &dataTypeTemp, length: 1))

    // dataSize is Int64, value is fileData.size
    var dataSizeTemp = dataSize.bigEndian
    var packSizeData: NSData = NSData(bytes: &dataSizeTemp, length: 4)
    sendData.appendData(packSizeData)
    sendData.appendData(NSData(bytes: [0] as Array<Int>, length: 25))

    sendData.appendData(fileData)

    // send data
    socket?.writeData(data, withTimeout: -1, tag: 0)
    socket?.readDataWithTimeout(-1, tag: 0)

发送设备的每件事情都可以,接收设备上的问题 收到四个包。每个数据包的大小都不同,但我只是在发送方设备上发送一次,而套接字标题是混乱的。

    // receiver device
    func socket(sock: GCDAsyncSocket!, didReadData data: NSData!, withTag tag: Int) {
            sock.readDataWithTimeout(-1, tag: 0)
            println(data)
            // PACKET_HEADER_LENGTH is 32
            var packetHeader: NSData = data.subdataWithRange(NSMakeRange(0, PACKET_HEADER_LENGTH))

            var packetContent: NSData = data.subdataWithRange(NSMakeRange(PACKET_HEADER_LENGTH, data.length - PACKET_HEADER_LENGTH))

            var headerVersion: Int16 = 0
            headerPacket.getBytes(&headerVersion, range: NSMakeRange(0, 2))
            // headerVersion is wrong, not 1
            headerVersion = headerVersion.bigEndian

            // packetType is wrong, not 0
            var packetType: Int = 0
            headerPacket.getBytes(&packetType, range: NSMakeRange(2, 1))

            var packetSize: Int64 = 0
            headerPacket.getBytes(&packetSize, range: NSMakeRange(3, 4))
            packetSize = packetSize.bigEndian
    }

我发现了一些关于读取数据的讨论: Having trouble programming streams

在数据末尾添加[GCDAsyncSocket CRLFData],在didReadData之前使用数据添加readDataToData:[GCDAsyncSocket CRLFData],但也无法解决问题。

任何人都可以帮助我吗?谢谢!

1 个答案:

答案 0 :(得分:0)

嗯..我知道如何解决这个问题。

当我向收件人发送数据包时,是这样的:

64kb ... send
64kb ... send
64kb ... send
// ... send other datas to finish

在接收设备上:

64kb ... waiting other datas
64kb ... waiting other datas
64kb ... OK call GCDAsyncSocket.didReadData delegate
// clear buffer
64kb ... waiting other datas
64kb ... OK call GCDAsyncSocket.didReadData delegate

因此,当接收数据时,需要保存一个缓冲文件,当发送完成时,将缓冲区文件处理到实际文件。

如果有人知道如何设置GCDAsyncSocket缓冲区大小,请告诉我。

希望我能帮助别人,谢谢。