【问题标题】:How to Transfer Large Files over wifi in iOS如何在 iOS 中通过 wifi 传输大文件
【发布时间】:2013-03-27 15:04:33
【问题描述】:

我从 Apple 网站下载了WiTap 代码。它用于通过本地 wifi 网络传输数据。我正在一个项目中作为客户端 - 服务器架构进行交互。我正在将 NSData 从客户端发送到服务器。

我做了两个项目;一个用于客户端,一个用于服务器

在客户端项目中,我进行了以下更改 为此,我通过添加以下方法修改了 AppController.m 文件

AppController.m(客户端)

- (void)sendData:(NSData*)pobjData
{
    assert(self.streamOpenCount == 2);

    if ( [self.outputStream hasSpaceAvailable] ) 
    {
        NSInteger   bytesWritten;

        NSUInteger length = [pobjData length];

        bytesWritten = [self.outputStream write:[pobjData bytes] maxLength:[pobjData length]];

        NSLog(@"written bytes -> %d",bytesWritten);
    }
}

然后通过调用这个方法我发送数据。

在服务器端项目中,我通过修改以下方法修改了 AppController.m 文件

AppController.m(服务器端)

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

    switch(eventCode) {

        case NSStreamEventOpenCompleted: {
            self.streamOpenCount += 1;
            assert(self.streamOpenCount <= 2);

            // Once both streams are open we hide the picker and the game is on.

            if (self.streamOpenCount == 2) {
                [self dismissPicker];

                [self.server deregister];
            }
        } break;

        case NSStreamEventHasSpaceAvailable: {
            assert(stream == self.outputStream);
            // do nothing
        } break;

        case NSStreamEventHasBytesAvailable:
        {
            if (stream == self.inputStream)
            {

                NSInteger bytesRead;
                uint32_t buffer[32768];

                NSMutableData *_data = [NSMutableData data];

                // Pull some data off the network.
                bytesRead = [self.inputStream read:buffer maxLength:sizeof(buffer)];
                if (bytesRead == -1) {

                } else if (bytesRead == 0) {

                } else {
                    // FIXME: Popup an alert

                    const long long expectedContentLength = bytesRead;
                    NSUInteger expectedSize = 0;

                    // expectedContentLength can be represented as NSUInteger, so cast it:
                    expectedSize = (NSUInteger)expectedContentLength;

                    [_data appendBytes:buffer length:expectedSize];

                    NSLog(@"\"Data received has length: %d", _data.length);

                    [self performSelector:@selector(getData:) withObject:_data afterDelay:1.0];
                }
            }
        }
            break;

        default:
            assert(NO);
            // fall through
        case NSStreamEventErrorOccurred:
            // fall through
        case NSStreamEventEndEncountered: {
            [self setupForNewGame];
        } break;
    }
}

并添加了将接收到的数据写入文件的方法

     #define kUserDirectoryPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)

-(void)getData:(NSMutableData *)pData
{
                NSFileManager *tmpmanager = [NSFileManager defaultManager];
                [tmpmanager createFileAtPath:[AppController getDocumentDirectoryPath:[NSString stringWithFormat:@"%@.png",[NSDate date]]] contents:pData attributes:nil];
}


+(NSString*)getDocumentDirectoryPath:(NSString*)pStrPathName
{
            NSString *strPath=nil;

            if(pStrPathName)
                strPath = [[kUserDirectoryPath objectAtIndex:0] stringByAppendingPathComponent:pStrPathName];

            return strPath;
}

我将 .png 文件转换为 NSData 并将它们从客户端发送到服务器端。服务器将文件下载到文档目录

问题是,当我从客户端传输文件时,它会被下载到文档目录的服务器端。在小文件的情况下一切正常。如果文件大小超过 8kB ,则写入文档目录的文件会损坏。

请帮助我发送大文件。

【问题讨论】:

    标签: iphone ios bonjour nsstream


    【解决方案1】:

    你可以使用 AsyncSocket,可以从

    下载

    https://github.com/roustem/AsyncSocket,

    这是一个基于 CFSocket 和 CFNetwork 构建的 Objective-C 包装器,它可以处理本地 wifi 上的 TCP/UDP 协议的大量数据传输。

    你可以在这里找到 wiki https://github.com/darkseed/cocoaasyncsocket/wiki/iPhone

    这个类很简单,很容易实现。试试看

    【讨论】:

    • 我先尝试过,但在那种情况下,我也遇到了同样的问题。我曾经通过 UDP 传输,我也无法发送大于 9 kB 的文件..
    • github.com/robbiehanson/CocoaAsyncSocket 是 CocoaAsyncSocket 的官方 GitHub 存储库。
    • 尝试在 AsyncSocket.m 中更改“#define WRITE_CHUNKSIZE (1024 * 4) // 每次写入通道的大小限制”
    【解决方案2】:

    问题是您的代码直到最后都不会循环收集所有可用数据(或者循环发送所有数据)。因此,您只会收到第一个数据缓冲区。如果图像很小,则可以,如果图像较大,则永远不会。

    您需要编写代码,以便在有缓冲区空间时继续发送,直到发送所有数据并继续读取数据(到NSMutableData 实例变量,而不是局部变量)直到到达流的末尾.

    【讨论】:

      【解决方案3】:

      您已经创建了一个 Web 服务,您需要在其中放置系统的 IP 地址,您想要发送文件的位置,然后当您可以使用输入的 IP 地址连接时,您可以发送 Base64 和 NSData 格式的文件.

      【讨论】:

      • 我需要把那个网络服务放在哪里:D,请阅读整个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多