Как переносить большие файлы через Wi-Fi в iOS

Я загрузил WiTap Код с веб-сайта Apple. Его для передачи данных по локальной сети Wi-Fi. Я работаю над проектом для взаимодействия в качестве архитектуры клиент-сервер. Я отправляю 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);
    }
}

Затем, вызывая этот метод, я отправляю данные.

В проекте на стороне сервера я сделал следующие chagnes для этого, я модифицировал файл 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 и отправляю их с клиентской стороны на сервер. сервер загружает файл в Каталог документов

Дело в том, что когда я передаю файл с клиентской стороны, он загружается на сервер в каталоге документа. Все работает отлично в случае крошечных файлов. Если размер файла превышает 8 КБ, файл, записанный в каталоге документа, поврежден.

Пожалуйста, помогите мне отправить большие файлы.

Ответ 1

Проблема заключается в том, что ваш код не зацикливается, чтобы собрать все доступные данные до конца (или цикл для отправки всех данных). Таким образом, вы получаете только первый буфер данных. Если изображение мало, тогда это работает нормально, если изображение больше, чем никогда.

Вам нужно написать код, чтобы он продолжал отправлять, когда есть буферное пространство, пока все данные не будут отправлены и не будут читать данные (в переменную экземпляра NSMutableData, а не локальную переменную), пока не будет достигнут конец потока.

Ответ 2

Вы можете использовать AsyncSocket, который можно загрузить с

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

это оболочка objective-c, построенная на CFSocket и CFNetwork, она может обрабатывать большой объем передачи данных с протоколом TCP/UDP на локальном Wi-Fi.

Вы можете найти wiki здесь https://github.com/darkseed/cocoaasyncsocket/wiki/iPhone

Класс очень прост и прост в реализации. Попробуйте

Ответ 3

Вы создали веб-службу, где вам нужно поместить IP-адрес системы, где вы хотите отправить файл, и после этого, когда вы можете подключиться к указанному IP-адресу, вы можете отправить файл в формате Base64 и NSData.