通过TCP将JPEG从iPhone发送到PC

时间:2013-03-19 11:14:54

标签: c++ iphone tcp

如果从客户端发送的JPEG图像数据与图像不完整时在服务器上读取的大小不匹配,如何防止崩溃?

  1. 客户端:发送4个字节的图像长度信息-------->服务器:读取4个字节。
  2. 客户端:发送x字节的图像数据--------------->服务器:读取x个字节。
  3. 我使用sampleBuffer(AVFoundation)在iPhone上创建JPEG图像,在发送图像数据之前发送每个图像的长度。图像以一定的时间间隔连续发送。我使用Microsoft Vsual Studio 2005(C ++)接收数据并使用OpenCV显示图像。

    iPhone(客户端):

    // AVCaptureSession delegate
    - (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection 
    { 
    
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
        CVPixelBufferLockBaseAddress(imageBuffer,0); 
    
        uint8_t *baseAddress = (uint8_t *)CVPixelBufferGetBaseAddress(imageBuffer); 
        size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); 
        size_t width = CVPixelBufferGetWidth(imageBuffer); 
        size_t height = CVPixelBufferGetHeight(imageBuffer);  
    
        CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
        CGContextRef newContext = CGBitmapContextCreate(baseAddress, width, height, 8, bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
        CGImageRef newImage = CGBitmapContextCreateImage(newContext); 
    
        CGContextRelease(newContext); 
        CGColorSpaceRelease(colorSpace);
    
        [self.customLayer performSelectorOnMainThread:@selector(setContents:) withObject: (id) newImage waitUntilDone:YES];
    
        UIImage *image= [UIImage imageWithCGImage:newImage scale:1.0 orientation:UIImageOrientationRight];
        NSData *data = UIImageJPEGRepresentation(image, 0.5);
    
        // Send image length bytes
        uint32_t length = (uint32_t)htonl([data length]);
        [_outputStream write:(uint8_t *)&length maxLength:4];
    
        // Send image data bytes
        [_outputStream write:(const uint8_t *)[data bytes] maxLength:[data length]];
    
        CGImageRelease(newImage);
        CVPixelBufferUnlockBaseAddress(imageBuffer,0);
        [pool drain];
    }
    

    PC - VS2005 C ++(服务器):

    cvNamedWindow("image", CV_WINDOW_AUTOSIZE);
    
    std::vector<char> buf;
    
    for(int i=0; i < 1000; i++) {
    
        typedef unsigned __int32 uint32_t;
        uint32_t len;
        int lengthbytes = 0;
        int databytes = 0; 
    
        // Receive image length bytes
        lengthbytes = recv(clientSocket, (char *)&len, sizeof(len), 0); 
    
        len = ntohl(len);
    
        buf.clear();
        buf.resize(len);
    
        // Receive image data bytes ()
        databytes = recv(clientSocket, &buf[0], buf.size(), 0);
    
        // Display image
        Mat matrixJpeg = imdecode(Mat(buf), 1);
        IplImage object = matrixJpeg;
        IplImage* fIplImageHeader = &object;
        cvShowImage("image", fIplImageHeader);
        cvWaitKey(50);
    }
    

1 个答案:

答案 0 :(得分:0)

以下是我的问题的解决方案:

cvNamedWindow("image", CV_WINDOW_AUTOSIZE);

std::vector<char> buf;

for(int i=0; i < 1000; i++) {

    typedef unsigned __int32 uint32_t;
    uint32_t len;
    int lengthbytes = 0;
    int databytes = 0; 

    // Receive image length bytes
    lengthbytes = recv(clientSocket, (char *)&len, sizeof(len), 0);

    len = ntohl(len);

    buf.clear();
    buf.resize(len);

    // Receive image data bytes      
    databytes = recv(clientSocket, &buf[0], buf.size(), 0);

    if ( buf[0] == (char)0xff && buf[1] == (char)0xd8 && buf[buf.size() - 2] == (char)0xff && buf[buf.size() -1] == (char)0xd9) {

        // Display image if it's a complete JPEG file with SOF = FF D8 and EOF = FF D9
        Mat matrixJpeg = imdecode(Mat(buf), 1);
        IplImage object = matrixJpeg;
        IplImage* fIplImageHeader = &object;
        cvShowImage("image", fIplImageHeader);
        cvWaitKey(50);

    }else{

        // Clear buffer and move to the SOF of the next image data
        buf.clear();
        buf.resize(2);

        while(recv(clientSocket, &buf[0], 1, 0) == 1){     
            if(buf[0] == (char)0xff) { 
                databytes1 = recv(clientSocket, &buf[1], 1, 0);
                if(buf[1] == (char)0xd9 ) { 
                    buf.clear();
                }
            }
        }
    }
}