我正在使用GCDAsyncSocket。编写用于在两台设备之间传输文件的应用程序时,在接收文件时遇到一些问题:
当我想向另一个接收设备(iOS设备或iOS模拟器)发送大约60kb的文本文件时,需要在数据之前添加一些数据包信息,如下所示:
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],但也不能解决问题。
有人能帮我吗?谢谢!
最佳答案
好。。我知道如何解决这个问题。
当我将数据包发送到接收器时,如下所示:
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缓冲区大小,请告诉我。
希望我能帮助其他人,谢谢。
关于ios - 使用GCDAsyncSocket传输文件接收器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25460464/