1

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を通過していません。

だから、私は明らかに何かが欠けています。このようなデータのソケットプログラミングとエンコード/デコードは、私にとって比較的新しいものなので、おそらく私はばかです。

大変助かります!

ありがとう

ガレス

4

1 に答える 1