我正在尝试将一些字符串和图像数据从 python 脚本发送到在 OSX 上运行的目标 C 应用程序。
我正在使用 GCDAsyncSocket 收集传输的数据,并将其附加到 NSMutableData 直到服务器断开连接。然后我正在处理该 NSData 并将其拆分为原始部分。
传输的数据包括以下内容:
ID 字符串,填充到 16 个字节。
图像编号字符串,填充到 16 个字节。
原始图像数据。
终止字符串,填充到 16 个字节。
问题是我没有接收/获取最后一块数据,我最终错过了 JPEG 图像的结尾,导致图像损坏(尽管大部分显示),并且缺少终止字符串。
这是我使用 GCDAsyncSocket 来获取数据并处理它的代码:
插座连接:
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
{
// This method is executed on the socketQueue (not the main thread)
@synchronized(connectedSockets)
{
[connectedSockets addObject:newSocket];
}
NSString *host = [newSocket connectedHost];
UInt16 port = [newSocket connectedPort];
dispatch_async(dispatch_get_main_queue(), ^{
@autoreleasepool {
[self logInfo:FORMAT(@"Accepted client %@:%hu", host, port)];
}
});
[newSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
}
接收到的套接字数据
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
// This method is executed on the socketQueue (not the main thread)
dispatch_async(dispatch_get_main_queue(), ^{
@autoreleasepool {
NSLog(@"Thread Data Length is %lu", (unsigned long)[data length]);
if (!imageBuffer){
imageBuffer = [[NSMutableData alloc]init];
}
[imageBuffer appendData:[data subdataWithRange:NSMakeRange(0, [data length])]];
NSLog(@"Total Data Length is %lu", (unsigned long)[imageBuffer length]);
}
});
// Echo message back to client
[sock writeData:data withTimeout:-1 tag:ECHO_MSG];
[sock readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
}
插座断开
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err
{
if (sock != listenSocket)
{
dispatch_async(dispatch_get_main_queue(), ^{
@autoreleasepool {
[self logInfo:FORMAT(@"Client Disconnected")];
NSData *cameraNumberData;
NSData *imageNumberData;
NSData *imageData;
NSData *endCommandData;
//if ([data length] > 40){
cameraNumberData = [imageBuffer subdataWithRange:NSMakeRange(0, 16)];
imageNumberData = [imageBuffer subdataWithRange:NSMakeRange(16, 16)];
imageData = [imageBuffer subdataWithRange:NSMakeRange(32, [imageBuffer length]-34)];
endCommandData = [imageBuffer subdataWithRange:NSMakeRange([imageBuffer length]-16, 16)];
//}
NSString *cameraNumberString = [[NSString alloc] initWithData:cameraNumberData encoding:NSUTF8StringEncoding];
NSString *imageNumberString = [[NSString alloc] initWithData:imageNumberData encoding:NSUTF8StringEncoding];
NSString *endCommandString = [[NSString alloc] initWithData:endCommandData encoding:NSUTF8StringEncoding];
NSImage* image = [[NSImage alloc]initWithData:imageData];
if (cameraNumberString)
{
NSLog(@"Image recieved from Camera no %@", cameraNumberString);
[self logMessage:cameraNumberString];
}
else
{
[self logError:@"Error converting received data into UTF-8 String"];
}
if (imageNumberString)
{
NSLog(@"Image is number %@", imageNumberString);
[self logMessage:imageNumberString];
}
else
{
[self logError:@"Error converting received data into UTF-8 String"];
}
if (image)
{
NSLog(@"We have an image");
[self.imageView setImage:image];
}
else
{
[self logError:@"Error converting received data into image"];
}
if (endCommandString)
{
NSLog(@"Command String is %@", endCommandString);
[self logMessage:endCommandString];
}
else
{
[self logError:@"No command string"];
}
//self.imageBuffer = nil;
}
});
@synchronized(connectedSockets)
{
[connectedSockets removeObject:sock];
}
}
}
我使用了wireshark,数据正在传输,只是没有通过GCDAsynSocket。
所以,我显然错过了一些东西。像这样的套接字编程和数据编码/解码对我来说相对较新,所以我可能是个白痴。
非常感谢帮助!
谢谢
加雷斯