如果从客户端发送的JPEG图像数据与图像不完整时在服务器上读取的大小不匹配,如何防止崩溃?
我使用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);
}
答案 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();
}
}
}
}
}