12

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

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

在客户端项目中,我进行了以下更改为此我通过添加以下方法修改了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 ,则写入文档目录的文件会损坏。

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

4

3 回答 3

1

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

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

于 2013-04-22T22:32:39.340 回答
0

您可以使用 AsyncSocket ,可以从

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

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

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

该类非常简单,易于实现。试一试

于 2013-04-05T09:33:39.937 回答
-1

You have make a web service from where you need to put IP address of the system, Where you want to send the file and after that when you can connected with the entered IP address you can send the file in Base64 and NSData format.

于 2013-04-25T05:22:28.347 回答