Использование класса NSNetService для создания TCP-соединения по протоколу SMB с папкой общего доступа на компьютере Windows. - PullRequest
2 голосов
/ 12 февраля 2011

Я пытался найти способ доступа к моей общей папке Windows с помощью iPhone. Желаемая функциональность является частью большого корпоративного приложения, которое я создаю. Вот кто-то, кто уже задавал подобный вопрос, но не повезло - Поддерживает ли iOS операции с файлами через SMB?

Теперь я обнаружил учебное пособие для разработчиков Apple под названием " SimpleNetworkStreams ", в котором NSNetService использует протокол x-SNSUpload поверх tcp, задав тип экземпляра NSNetService для протокола x-SNSUpload._tcp

Вот как они это сделали -

self.netService = [[[NSNetService alloc] initWithDomain:@"local." type:@"_x-SNSUpload._tcp." name:@"Test"] autorelease];

Так что, если я просто заменю _x-SNSUpload._tcp на _smb._tcp и запусту SMB-сервер на моем macbook. Я запускаю следующий набор команд для запуска SMB на моем MacBook

dns-sd -R Test _smb._tcp. "" 12345

nc -l 12345 > tmp.png

Затем я могу перенести изображение с моего iPhone в корневой каталог моего macbook. Я надеялся сделать то же самое с общей папкой на машине с Windows.

Имя общей папки - «общий доступ к тестам». Я явно поделился своей папкой «совместного доступа к тестам» на моем компьютере с полным контролем для всех. Полная информация о коде приведена ниже (после обновления)

Если я непосредственно наберу "smb: \\ 10.212.19.121" в своем браузере, я получу доступ к своей общей папке. Он открывает приложение поиска и дает мне возможность смонтировать папку «temp shared».


Обновление - множество лишнего текста, извлеченного сверху, и более подробные сведения о том, как SimpleNetworkStreams работает и что я настроил, приведены ниже.

Код взят из - SimpleNetworkStreams -

  1. Открыть поток типа NSInputStream для файла, который мы хотим отправить

//Open a stream for the file we're going to send

//filepath is a NSString with path to the file on iPhone

self.fileStream = [NSInputStream inputStreamWithFileAtPath:filepath]; 

assert(self.fileStream != nil); 

[self.fileStream open];
  1. Как говорится в документации Apple

    "вы можете либо создать объект NSNetService напрямую (если вы знаете точную информацию о хосте и порте), либо вы можете использовать объект NSNetServiceBrowser для поиска служб."

Объект NSNetService создается для сервера, на котором размещен SMB-сервер

// Open a stream to the server, finding the server via Bonjour.  Then configure 
// the stream for async operation.

//here's the tweak.
//original code looked like - 
//self.netService = [[[NSNetService alloc] initWithDomain:@"local." type:@"_x-SNSUpload._tcp." name:@"Test"] autorelease];

self.netService = [[[NSNetService alloc] initWithDomain:@"10.212.19.121" type:@"_smb._tcp." name:@"lanmanserver"] autorelease];

assert(self.netService != nil);

NSDictionary *newDict = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:@"domain\\username",@"password",@"C:\\Documents and Settings\\username\\Desktop\\test%20sharing",nil] forKeys:[NSArray arrayWithObjects:@"u",@"p",@"path",nil]];

[self.netService setTXTRecordData:[NSNetService dataFromTXTRecordDictionary:newDict]];

Получите объект потока вывода типа NSOutputStream в self.networkStream.

success = [self.netService getInputStream:NULL outputStream:&output];
assert(success);

self.networkStream = output;

[output release];

self.networkStream.delegate = self;
[self.networkStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

[self.networkStream open];

и затем делегат NSOutputStream перехватывает NSStreamEventHasSpaceAvailable, где мы буферизируем во входном файле и затем записываем этот буфер в наш объект NSOutputStream, т.е. networkStream

bytesWritten = [self.networkStream write:&self.buffer[self.bufferOffset] maxLength:self.bufferLimit - self.bufferOffset];

Ответы [ 2 ]

2 голосов
/ 05 марта 2011

Я думаю, вы неправильно поняли NSNetservice. NSNetService может использоваться для публикации Bonjour Информация о сетевых услугах в вашей сети. Он не создает сервер для вас, он просто сообщает клиентам, что есть сервер с доступным сервисом. Даже если такого сервера нет, он скажет клиенту, что он есть.

Попробуйте добрый браузер , чтобы увидеть, что делает NSNetService. Все записи, которые вы увидите, опубликованы NSNetServices.
Или вы можете опубликовать сервис с типом _afpovertcp._tcp. и посмотрите на боковую панель в Finder, чтобы понять, как используются NSNetServices.


dns-sd -R Test _smb._tcp. "" 12345
nc -l 12345 > tmp.png

Эти строки не имеют абсолютно никакого отношения к SMB. То, что вы рекламируете свой сервис как SMB, не означает, что ваш сервер действительно понимает SMB.
И nc (он же netcat) делает именно то, что предполагает его название. Он сбрасывает все, что вы отправляете ему в ваш файл. Не SMB, совсем нет.

А использование TXTRecords для аутентификации - плохая идея, каждый, кто подключен к вашей сети, получит TXTRecords.

Короче говоря, NSNetServices не поможет вам в создании SMB-соединений. Когда вы закончите работу с SMB-сервером, вы можете использовать NSNetServices, чтобы сообщить клиентам в вашей сети, что существует SMB-сервер. Но это не поможет вам в создании этого сервера.

1 голос
/ 05 марта 2011

Вы пробовали: self.netService = [[[NSNetService alloc] initWithDomain: @ "10.212.19.121" type: @ "_ smb._tcp.local" name: @ "lanmanserver"] autorelease];

...