【问题标题】:Receive an image on the iPhone (TCP Client)在 iPhone 上接收图像(TCP 客户端)
【发布时间】:2012-03-15 21:51:04
【问题描述】:

我正在 iPhone 上编写一个客户端。我想发送一些字符串,并从服务器接收图像。

我找到了这个教程(http://www.devx.com/wireless/Article/43551),它非常有用。如果我想接收字符串,它可以工作,但现在我想接收图像,但我无法使其工作。

这是我在 iPhone 接收数据时的代码。这是本教程和 JeremyP 的答案(http://stackoverflow.com/questions/4613218)的混合:

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {

switch(eventCode) {
    case NSStreamEventHasBytesAvailable: {
        if (data == nil) {
            data = [[NSMutableData alloc] init];
        }
        uint8_t buf[102400];
        unsigned int len = 0;
        len = [(NSInputStream *)stream read:buf maxLength:102400];

        if(len) {    
            [data appendBytes:(const void *)buf length:len];

            // Recibir img
    uint8_t size;  // Let's make sure size is an explicit width.

            NSInteger totalBytesRead = 0;
            NSInteger bytesRead = [iStream read: &size maxLength: sizeof size];
            while (bytesRead > 0 && totalBytesRead + bytesRead < sizeof size) {
                totalBytesRead+= bytesRead;
                bytesRead = [iStream read: &size + totalBytesRead maxLength: (sizeof size) - totalBytesRead];
            }
            if (bytesRead >= 0) {
                totalBytesRead += bytesRead;
            }
            else {
                // read failure, report error and bail
            }
            if (totalBytesRead < sizeof size) {
                // connection closed before we got the whole size, report and bail
            }
            size = ntohl(size);  // assume wire protocol uses network byte ordering

            NSMutableData* buffer = [[NSMutableData alloc] initWithLength: size];
            totalBytesRead = 0;
            bytesRead = [iStream read: [buffer mutableBytes] maxLength: size];
            while (bytesRead > 0 && totalBytesRead + bytesRead < size) {
                totalBytesRead+= bytesRead;
                bytesRead = [iStream read: [buffer mutableBytes] + totalBytesRead maxLength: size - totalBytesRead];
            }
            if (bytesRead >= 0) {
                totalBytesRead += bytesRead;
            }
            else {
                // read failure, report error and bail (not forgetting to release buffer)
            }
            if (totalBytesRead < size) {
                // connection closed before we got the whole image, report and bail (not forgetting to release buffer)
            }
            else {
                [buffer setLength: size];
            }

            imgResultado.image = [UIImage imageWithData: buffer];
            [buffer release];
            [data release];        
            data = nil;

        } 
        else {
            NSLog(@"No data.");
        }


    } break;
}}

它不起作用...你能帮帮我吗?

【问题讨论】:

    标签: iphone ios image tcp client-server


    【解决方案1】:

    如果您只想从服务器下载图像以显示,请查看以下内容:

    https://github.com/michaelkamprath/iPhoneMK/tree/master/Views/MKNetworkImageView

    iOS 有很多内置函数可以为您处理图像下载。也就是说,如果您可以将要下载的实体封装为单独的 URL(例如,Web 服务器)。

    但是,如果您尝试通过同一个 TCP 连接发送和接收数据,我强烈建议您改用更加 RESTful 的方法。部分原因是它更容易从客户端实现,部分原因是您不必(尽可能多地)担心底层 TCP 连接。

    【讨论】:

    • 图片不在网络中。服务器用客户端发送的数据生成图像,然后通过TCP连接发送图像。我必须在 iPhone 中对 TCP 客户端进行编程以接收并显示该图像。
    • 你知道服务器返回的是什么数据格式吗? imageWithData:仅适用于 JPG、PNG 等。如果您的服务器返回的是原始像素数据,那么这将不起作用。
    【解决方案2】:

    嗯,我是这样做的,但我不确定是否有更好的方法。

    - (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode {
    switch(eventCode) {
        case NSStreamEventHasBytesAvailable:
        {
            uint32_t max_size = 1000000;  // Max size of the received imaged.
            NSMutableData* buffer = [[NSMutableData alloc] initWithLength: max_size];
            NSInteger totalBytesRead = 0;
            NSInteger bytesRead = [(NSInputStream *)stream read: [buffer mutableBytes] maxLength: max_size];
            if (bytesRead != 0) {
                while (bytesRead > 0 && totalBytesRead + bytesRead < max_size) {
                    totalBytesRead+= bytesRead;
                    bytesRead = [(NSInputStream *)stream read: [buffer mutableBytes] + totalBytesRead maxLength: max_size - totalBytesRead];
                }
                if (bytesRead >= 0) {
                    totalBytesRead += bytesRead;
                }
                else {
                    // read failure, report error and bail (not forgetting to release buffer)
                }
                [buffer setLength: totalBytesRead];
                imgResultado.image = [UIImage imageWithData: buffer];
                [buffer release];
            }
        } break;
    }}
    

    使用此方法,接收到的图像必须小于 max_size。 如果您知道更好的方法来做到这一点,请告诉我! ;)

    【讨论】:

    • 这意味着您的服务器没有像您之前的代码所期望的那样在流的开头传输大小整数。这就是为什么您之前的代码不起作用的原因,因为如果图像数据,您有效地删除了前 4 个字节。
    • 因此,使用此代码,您最多可以接收 1000000 字节的图像。那几乎是1MB? (您的原始代码只有大约 100k?)只需尝试确认...
    • user523234 是的,客户端最多可以接收 1000000 字节的图像。 Claireware,这可能是一个很好的解释,我认为你是对的。这种方式比我的回答更安全,但是如果我想使用它,我需要修改服务器。
    • 对你有好处。当我做类似的事情时,我遇到了每个流 128K 的限制。所以我不得不将我的图像分解为
    • 我试过发送300k的图片,没有问题。服务器在visual basic中,我将图像转换为字节数组,然后在流上使用写函数:stream.Write(byteArray,0,byteArray.length)
    猜你喜欢
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    • 2013-07-25
    • 1970-01-01
    • 2010-11-18
    相关资源
    最近更新 更多