Отправка файлов через Socket (iOS) - PullRequest
2 голосов
/ 24 февраля 2012

Я создал приложение Simple Chat на основе сокета. Пост: Приложение для iPhone на базе сокетов помогло мне создать это.

Теперь я хочу отправлять / получать файлы через сокет. Пожалуйста, дайте мне указания относительно того, как я могу достичь этого.

Ура, Roshit

EDIT:

Код, используемый для подключения к сокету:

NSString *aHostName = @"xx.xx.xx.xx";
NSInteger aPort = 1234;

CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)aHostName, aPort, &readStream, &writeStream);

self.inputStream = (NSInputStream *)readStream;
self.outputStream = (NSOutputStream *)writeStream;

[self.inputStream setDelegate:self];
[self.outputStream setDelegate:self];

[self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[self.outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[self.inputStream open];
[self.outputStream open];

Код, используемый для отправки данных:

NSData *aData = [[NSData alloc] initWithData:[iRequestAPI dataUsingEncoding:NSASCIIStringEncoding]];
[self.outputStream write:[aData bytes] maxLength:[aData length]];
[aData release];

где iRequestAPI - строка, которая должна быть отправлена.

Теперь, когда я пытаюсь отправить файл через сокет, учитывая тот факт, что я конвертирую Файл в NSData и использую [self.outputStream write:[aData bytes] maxLength:[aData length]];, может быть вероятность того, что весь файл не будет отправлен из-за пропускной способности соединения. Если весь файл не отправлен, как убедиться, что остальная часть отправлена.

Это правильный подход для отправки файла через сокет. Пожалуйста, предложите ..

Ответы [ 2 ]

2 голосов
/ 19 сентября 2012

Если ваши NSData достаточно велики, вам нужно разрезать их на части. Вам понадобятся байты для их передачи. Например:

NSData *newData = UIImagePNGRepresentation([UIImage imageNamed:@"Default.png"]);
    int index = 0;
    int totalLen = [newData length];
    uint8_t buffer[1024];
    uint8_t *readBytes = (uint8_t *)[newData bytes];

    while (index < totalLen) {
        if ([outputStream hasSpaceAvailable]) {
            int indexLen =  (1024>(totalLen-index))?(totalLen-index):1024;

            (void)memcpy(buffer, readBytes, indexLen);

            int written = [outputStream write:buffer maxLength:indexLen];

            if (written < 0) {
                break;
            }

            index += written;

            readBytes += written;
        }
    }
1 голос
/ 19 марта 2012

Файлы содержат данные. Сетевые соединения (сокет или иное) передают данные. Вы могли бы просто открыть файл, прочитать данные и начать записывать те же самые данные в свой сокет. Однако ...

Возможно, вы хотите передать файл в контексте сеанса чата . Итак, вы захотите как-то разграничить файл, чтобы принимающая сторона соединения понимала, что данные, которые встречаются, являются файлом. И вы, вероятно, захотите перенести некоторые метаданные для файла, такие как имя, размер и т. Д.

Точно как вы делаете все, что полностью зависит от вас. Вы пишете код на обоих концах соединения, поэтому, если вы придумаете план и правильно его реализуете, вы сможете заставить его работать. Один подход будет использовать некоторую магическую строку, такую ​​как +++++++++++++, чтобы ограничить начало информации о файле. Если вы укажете количество байтов, вы можете записать столько байтов в соединение и ожидать, что другая сторона прочитает столько байтов. Другим способом сделать это было бы преобразование всего потока данных для включения метаинформации. Например, вы можете использовать формат на основе XML.

Это действительно зависит от вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...