【问题标题】:Uniquely identify client connecting to an NSNetService/NSStream唯一标识连接到 NSNetService/NSStream 的客户端
【发布时间】:2015-12-13 00:57:50
【问题描述】:

我在客户端应用程序和服务器应用程序之间打开两个 NSStreams 对(输入/输出),并且需要将这两个流关联到同一个服务器端对象。双流方法意味着 didAcceptConnectionWithInputStream 将被调用两次,每次来自客户端的流打开命令。两个打开命令将按顺序执行,一个紧接着另一个。我尝试使用两个打开将一起完成以在服务器端配对它们的事实,但是如果两个不同的客户端尝试同时连接,则肯定存在竞争条件和流混淆问题。

如果有一个键/值对可以在连接到服务时发送,我会发送一个客户端生成的 GUID 来识别客户端,这将是完美的。

虽然通过 IP 地址识别是一种可能的解决方案,因为客户端将位于本地网络上(不必遍历 NAT),但使用 NSNetService 实现似乎很复杂。

【问题讨论】:

  • 类似的协议,例如 SIP,使用第三个连接来传送监管信息。例如,您的客户端可以通过 TCP 连接到服务器并使用此连接与服务器交换信息“我刚刚连接到您,您端的端口号是 1234”或“我要连接,哪些 UDP 端口我应该使用吗?”- 然后服务器可以回复发送/接收端口并开始监听这些端口
  • 谢谢 - 我没想到的好主意。不幸的是, NSNetService 从端口号中抽象出来,因此根据传入的流它不可用,因此我认为该方法存在问题,原因与我不能使用 IP 地址相同。我希望在不使用底层编程的情况下解决这个问题。
  • 如果不能使用带外,则需要使用带内信令;流开头的数据需要以某种方式识别客户端
  • 不幸的是,didAcceptConnectionWithInputStream 方法中没有包含任何数据,这是当流被宣布到服务器时,所以这意味着等待客户端随后发送数据,同时维护一个未识别的流池.这是一种精心设计的方法,但除非有人提出更简单的方法,否则我可能会采用它。令我惊讶的是,没有(简单的)方法可以从 NSStream 获取 IP 地址。
  • 流是一个抽象对象,因此可能没有关联的 IP 地址。我可能会选择我的第一个选择;为客户端连接的广告服务。使用此服务向客户端告知要为其流连接的服务的(唯一)名称,然后宣传此新服务。

标签: ios cocoa nsnetservice


【解决方案1】:

上面 cmets 中的 Paulw11 帮助我整理了选项。我最终通过以下方式解决了问题:

我创建了一个 PendingStream 类来充当每个传入流请求(即输入和输出流对)的临时持有者,并将其添加到包含所有 PendingStream 对象的集合中。 PendingStream 被设置为流式传输的委托,以便它可以在输入流上接收来自客户端的传入数据。客户端然后发送一个标识符,该标识符也存储为 PendingStream 的一个属性。每次标识符从客户端到达时,PendingStream 都会回调创建它的原始对象(它是委托),以便可以迭代 PendingStreams 集并匹配基于客户端标识符标识的流对。找到匹配项后,将从集合中删除 PendingStream 对象,并将流对重新分配到需要它们的位置。

使用基于计时器的方法来确保没有 PendingStream 孤儿(两个匹配的流请求中只有一个到达)。

它比我想的要复杂一些,但效果很好。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-19
    • 2017-02-09
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多