如何在iOS上通过WiFi传输大文件

12

我从苹果的官方网站下载了名为WiTap 的代码,这是用于在本地Wi-Fi网络上传输数据的。我正在一个客户端 - 服务器架构的项目中工作。我正在将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,则写入文档目录的文件会损坏。

请帮助我能够发送大文件。

3个回答

1
问题在于你的代码没有循环以收集所有可用数据直到结束(或循环发送所有数据)。因此,你只能接收到第一个数据缓冲区。如果图像很小,那么这样就可以正常工作,但如果图像更大,则永远不会正常工作。
你需要编写代码,使其在有缓冲空间时保持发送,直到发送完所有数据,并继续读取数据(将其读入一个NSMutableData实例变量,而不是局部变量),直到达到流的末尾。

0

我先尝试了一下,但在那种情况下我仍然遇到了同样的问题。我曾经使用UDP传输,但是即使在那里,我也无法发送大于9KB的文件。 - HarshIT
https://github.com/robbiehanson/CocoaAsyncSocket 是 CocoaAsyncSocket 的官方 GitHub 存储库。 - zadr
尝试更改 AsyncSocket.m 中的 "#define WRITE_CHUNKSIZE(1024 * 4)//每个写入传递的大小限制"。 - spider1983

-1
你需要创建一个网络服务,其中你需要输入系统的IP地址,以及你想要发送文件的目标地址。当你成功连接到输入的IP地址后,你可以以Base64和NSData格式发送文件。

我需要把那个 Web 服务放在哪里呢?请阅读完整个问题。 - HarshIT

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接