简体   繁体   English

使用 NSNetService 类与 Windows 机器上共享的文件夹建立 SMB tcp ip 连接

[英]Using NSNetService class to make an SMB tcp ip connection to a folder shared on windows machine

I have been trying to figure out a way to access my windows shared folder using iPhone.我一直在想办法使用 iPhone 访问我的 Windows 共享文件夹。 The desired functionality is part of bigger enterprise app I am building.所需的功能是我正在构建的更大企业应用程序的一部分。 Here is someone who has already asked a similar question but no luck - Does iOS support file operations via SMB?这是已经问过类似问题但没有运气的人 - iOS 是否支持通过 SMB 进行文件操作?

Now, I have found apple developer tutorial called " SimpleNetworkStreams " which employs NSNetService to use x-SNSUpload protocol over tcp by setting type of NSNetService instance to protocol x-SNSUpload._tcp现在,我找到了名为“ SimpleNetworkStreams ”的苹果开发者教程,它通过将 NSNetService 实例的类型设置为协议x-SNSUpload._tcp来使用 NSNetService 通过 tcp 使用 x-SNSUpload 协议

Here is how they have done it -这是他们如何做到的 -

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

So if I just replace _x-SNSUpload._tcp with _smb._tcp and run SMB server on my macbook.因此,如果我只是将_x-SNSUpload._tcp替换为_smb._tcp并在我的 macbook 上运行 SMB 服务器。 I run following set of commands to start SMB on my macbook我运行以下一组命令在我的 macbook 上启动 SMB

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

nc -l 12345 > tmp.png

Then I am able to transfer a picture in my iPhone to my macbook's root directory.然后我就可以将 iPhone 中的图片传输到我的 macbook 的根目录。 I was hoping to do the same with shared folder on windows machine.我希望对 Windows 机器上的共享文件夹做同样的事情。

The name of the share folder is "test sharing".共享文件夹的名称是“测试共享”。 I have explicitly shared my 'test sharing' folder in my windows machine with full control to everyone.我已经明确地在我的 Windows 机器中共享了我的“测试共享”文件夹,并且所有人都可以完全控制。 The complete details of code is put below (after Update)代码的完整细节如下(更新后)

If I directly type in "smb:\\\\10.212.19.121" on my browser I am able to access my shared folder.如果我直接在浏览器上输入“smb:\\\\10.212.19.121”,我就可以访问我的共享文件夹。 It opens the finder application and gives me an option to mount the "temp sharing" folder.它会打开 finder 应用程序,并为我提供一个选项来安装“临时共享”文件夹。


Update - lot of redundant text taken out from above and better details on how SimpleNetworkStreams work and what I have tweaked is put below.更新 -从上面取出的大量冗余文本以及关于 SimpleNetworkStreams 如何工作和我调整的更好的细节放在下面。

The code is taken from - SimpleNetworkStreams -代码取自 - SimpleNetworkStreams -

  1. Open the stream of type NSInputStream for the file we want to send为我们要发送的文件打开 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. As how apple documentation says正如苹果文档所说

"you can either create an NSNetService object directly (if you know the exact host and port information) or you can use an NSNetServiceBrowser object to browse for services. " “你可以直接创建一个 NSNetService 对象(如果你知道确切的主机和端口信息)或者你可以使用一个 NSNetServiceBrowser 对象来浏览服务。”

An object of NSNetService is instantiated for the server which hosts SMB server为承载 SMB 服务器的服务器实例化 NSNetService 的对象

// 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]];
 

Get the output stream object of type NSOutputStream into self.networkStream.将 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];

and then the NSOutputStream delegate catches NSStreamEventHasSpaceAvailable where we buffer in the input file and then write that buffer to our NSOutputStream object ie networkStream然后 NSOutputStream 委托捕获 NSStreamEventHasSpaceAvailable 我们在输入文件中缓冲的位置,然后将该缓冲区写入我们的 NSOutputStream 对象,即 networkStream

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

I think you misunderstood NSNetservice.我想你误解了 NSNetservice。 NSNetService can be used to publish Bonjour Information about network services in your network. NSNetService 可用于发布有关网络中网络服务的Bonjour信息。 It doesn't create a server for you, it just tells the clients that there is a server with the service available.它不会为您创建服务器,它只是告诉客户端有一个提供服务的服务器。 Even if there is no such server it will tell the client that there is one.即使没有这样的服务器,它也会告诉客户端有一个。

Try bonjour browser to see what NSNetService does.试试bonjour 浏览器看看 NSNetService 做了什么。 All the entries you will see are published NSNetServices.您将看到的所有条目都是已发布的 NSNetServices。
Or you could publish a service with the type _afpovertcp._tcp.或者您可以发布类型为 _afpovertcp._tcp 的服务。 and watch the sidebar in finder to get an idea how NSNetServices are used.并查看 finder 中的侧边栏以了解如何使用 NSNetServices。


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

These lines have absolutely nothing to do with SMB.这些行与 SMB 完全无关。 Just because you are advertising your service as SMB doesn't mean that your server actually understands SMB.仅仅因为您将服务宣传为 SMB 并不意味着您的服务器实际上了解 SMB。
And nc (aka netcat) does exactly what its name suggests.并且 nc(又名 netcat)正如它的名字所暗示的那样。 It dumps everything you send to it into your file.它将您发送给它的所有内容转储到您的文件中。 Not SMB, not at all.不是 SMB,根本不是。

And using TXTRecords for Authentication is a bad idea, everybody who is connected to your network will get the TXTRecords.并且使用 TXTRecords 进行身份验证是一个坏主意,连接到您网络的每个人都将获得 TXTRecords。

To make a long story short, NSNetServices won't help you with creating SMB connections.长话短说, NSNetServices不会帮助您创建 SMB 连接。 Once you are done with the SMB Server you can use NSNetServices to tell clients in your network that there is a SMB Server.完成 SMB 服务器后,您可以使用 NSNetServices 告诉网络中的客户端存在 SMB 服务器。 But it won't help you in creating this server.但它不会帮助您创建此服务器。

你有没有试过: self.netService = [[[NSNetService alloc] initWithDomain:@"10.212.19.121" type:@"_smb._tcp.local" name:@"lanmanserver"] autorelease];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM