【问题标题】:Using NSNetService class to make an SMB tcp ip connection to a folder shared on windows machine使用 NSNetService 类与 Windows 机器上共享的文件夹建立 SMB tcp ip 连接
【发布时间】:2011-06-25 22:01:40
【问题描述】:

我一直在尝试找出一种方法来使用 iPhone 访问我的 windows 共享文件夹。所需的功能是我正在构建的更大企业应用程序的一部分。这是一个已经问过类似问题但没有运气的人 - Does iOS support file operations via SMB?

现在,我找到了名为“SimpleNetworkStreams”的苹果开发者教程,它使用 NSNetService 通过将 NSNetService 实例的类型设置为协议 x-SNSUpload._tcp 来通过 tcp 使用 x-SNSUpload 协议

这是他们的做法 -

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

因此,如果我只是将 _x-SNSUpload._tcp 替换为 _smb._tcp 并在我的 macbook 上运行 SMB 服务器。我运行以下命令集在我的 macbook 上启动 SMB

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

nc -l 12345 > tmp.png

然后我可以将 iPhone 中的图片传输到我的 macbook 的根目录。我希望对 Windows 机器上的共享文件夹做同样的事情。

共享文件夹的名称是“测试共享”。我已经在我的 Windows 机器中明确共享了我的“测试共享”文件夹,并且所有人都可以完全控制。代码的完整细节放在下面(更新后)

如果我在浏览器上直接输入“smb:\\10.212.19.121”,我就可以访问我的共享文件夹。它会打开 finder 应用程序,并为我提供挂载“临时共享”文件夹的选项。


更新 - 从上面删除的大量冗余文本以及有关 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. 正如苹果文档所说的那样

"您可以直接创建一个 NSNetService 对象(如果您知道确切的主机和端口信息),也可以使用 NSNetServiceBrowser 对象来浏览服务。"

为托管 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]];
 

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

【问题讨论】:

    标签: iphone share smb nsnetservice


    【解决方案1】:

    我认为你误解了 NSNetservice。 NSNetService 可用于发布Bonjour 网络中有关网络服务的信息。它不会为您创建服务器,它只是告诉客户端有可用服务的服务器。即使没有这样的服务器,它也会告诉客户端有一个。

    试试bonjour browser 看看 NSNetService 做了什么。您将看到的所有条目都是已发布的 NSNetServices。
    或者,您可以发布类型为 _afpovertcp._tcp 的服务。并观看 finder 中的侧边栏,了解如何使用 NSNetServices。


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

    这些行与 SMB 完全无关。仅仅因为您将服务宣传为 SMB 并不意味着您的服务器实际上理解 SMB。
    nc(又名 netcat)正如其名称所暗示的那样。它将您发送给它的所有内容转储到您的文件中。不是中小企业,根本不是。

    使用 TXTRecords 进行身份验证是一个坏主意,连接到您网络的每个人都会获得 TXTRecords。

    长话短说,NSNetServices 不会帮助您创建 SMB 连接。 完成 SMB 服务器后,您可以使用 NSNetServices 告诉网络中的客户端存在 SMB 服务器。但它不会帮助您创建此服务器。

    【讨论】:

    • @fluchtpunkt 我没有使用 NSNetService 创建 SMB 服务器。我可以在 macbook 的浏览器中使用 smb:\\10.212.19.121 连接到 windows 共享文件夹(10.212.19.121 是 windows m/c 的 IP 地址)。它还在我连接时对我进行身份验证。所以 SMB 服务已经在运行。我想在 iPhone 中使用 NSNetService 对象作为客户端来连接 10.212.19.121 m/c & 为此我正在使用self.netService = [[[NSNetService alloc] initWithDomain:@"10.212.19.121" type:@"_smb._tcp." name:@"lanmanserver"] autorelease];。我在本地客户端 NSNetService 对象中设置 TXTRecords..
    • NSNetService 既不是客户端也不是服务器。它与 SMB 无关。如果你想发现 SMB-Servers,你可以使用 NSNetServiceBrowser,但你必须自己实现 smb 客户端。如果 NSNetService 是本地的(即未发布),那么它没有理由存在。你完全误解了 NSNetService 的使用。它只能用于“你好,我能理解这个协议,请在这个ip和这个端口连接”-广播。与实际服务器或客户端无关。你必须自己实现这些。
    • @fluchtpunkt 您认为我正在尝试做的事情可能有些混乱。我试图让这个问题更加自我解释。感谢您的回复
    • 好的,不知道可以手动创建远程 NSNetService,但很有意义。所以现在你已经连接到服务器了,但这就像一个哑管道。您在一端放入的内容在另一端完全一样。但对方只懂smb,你不说什么。所以现在你必须实现 smb 协议。服务器解析和打开输入和输出流是一个开始,但它与将文件传输到 smb 或从 smb 传输文件所需的费用相差 1%。您不能只将文件推送到网络流中。您必须将文件封装成 smb 消息。
    • 在 iphone 和 macbook 之间不起作用。至少没有超过 smb,你使用过 netcat。并且您将 netcat 输出重定向到一个文件中。如果你在 Windows 上安装 cygwin 和 netcat,你也可以这样做。但这与 smb 无关。 SNS 只是苹果为他们编写的服务的任意名称。您可以随意命名这些服务。它们只是名字。你在服务器上发布了一个 NSNetservice,其类型为 _foo._tcp。并在客户端上使用 NSNetServiceBrowser 开始搜索相同类型。
    【解决方案2】:

    您是否尝试过: self.netService = [[[NSNetService alloc] initWithDomain:@"10.212.19.121" type:@"_smb._tcp.local" name:@"lanmanserver"] autorelease];

    【讨论】:

    • 我很确定@fluchtpunkt 的答案和cmets。此 NSNetService 不会为您进行 SMB 打包。但是,我确实尝试了您的建议。没用。谢谢回复..
    猜你喜欢
    • 1970-01-01
    • 2021-05-24
    • 2013-09-08
    • 2018-07-26
    • 2013-12-24
    • 1970-01-01
    • 2020-01-14
    • 2011-01-11
    • 1970-01-01
    相关资源
    最近更新 更多