PythonスクリプトからOSXで実行されている目的のCアプリケーションに文字列と画像データを送信しようとしています。
GCDAsyncSocket を使用して送信されたデータを収集し、サーバーが切断されるまで NSMutableData に追加します。次に、その NSData を処理し、元の部分に分割しています。
送信されるデータは、次のもので構成されます。
16 バイトに入力された ID 文字列。
画像番号の文字列で、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を通過していません。
だから、私は明らかに何かが欠けています。このようなデータのソケットプログラミングとエンコード/デコードは、私にとって比較的新しいものなので、おそらく私はばかです。
大変助かります!
ありがとう
ガレス