在 Swift 中像在 Java 中一样使用套接字

Posted

技术标签:

【中文标题】在 Swift 中像在 Java 中一样使用套接字【英文标题】:Using sockets in Swift like in Java 【发布时间】:2014-09-11 20:48:33 【问题描述】:

如果我想连接到服务器,我会在 Java 中打开一个 Socket 并使用端口和主机地址对其进行初始化,然后检索输入/输出流并读取/写入我想要的任何内容。

在 Swift 中我很难做到这一点,因为它不是这样构建的,我真的很想看到一个简单的例子来说明如何连接到服务器、检索流并使用它们。

编辑1:

这是@Grimxn 引用之后的测试代码。

var host = "http://google.com"
var readStream :CFReadStreamRef
var writeStream :CFWriteSteamRef
var socket = CFStreamCreatePairWithSocketToHost(nil, host, 80, readStream, writeStream)

主要问题:

    初始化上面的两个流还需要使用我一无所知的CFAllocator。使用 kCFAllocatorDefault 并没有多大帮助,同样的错误。

    以上代码返回此错误:无法将表达式的类型“Void”转换为 UInt32 类型

    例如,当我使用 UInt32(80) 构造 UInt32 时,错误是:找不到 ' 的重载init' 接受提供的参数。

感谢您的帮助!

【问题讨论】:

你看过developer.apple.com/library/mac/documentation/Cocoa/Conceptual/…吗? 是的,我做到了。我在使用 CFStreamCreatePairWithSocketToHost 时遇到问题。对于这个简单的代码,我收到此错误无法将表达式的类型“Void”转换为 UInt32 类型。当我使用 '80' 作为参数初始化 UInt32 对象时也会发生这种情况。在这种情况下,错误是:找不到接受提供的参数的“init”的重载。 var host = "google.com" var readStream :CFReadStreamRef var writeStream :CFWriteStreamRef var socket = CFStreamCreatePairWithSocketToHost(nil, host, 80, readStream, writeStream) Swift 中的一个简单示例将解决我很多问题 您可以发布您尝试过的内容吗?人们更容易处理实际代码,而不是猜测你可能做了什么...... 当然,我刚刚编辑了评论,我遇到了一个问题,使它看起来正确而不是一团糟。感谢您提供这么多帮助。 有什么新的@Grimxn 吗? 【参考方案1】:

我自己想通了,希望得到解释的人请提前阅读;

有多种方法可以使用 Sockets 与本地应用程序或远程服务器进行通信。

原帖中描述的问题是获取输入/输出流并让它们工作。 (在这篇文章的末尾,我的另一篇文章解释了如何使用这些流)

NSStream 类有一个名为 getStreamsToHost 的静态方法(swift 中的类函数)。 所有你需要准备的是一个用真实主机地址、端口号、对 NSInputStream obj 以及 NSOutputStream obj 的引用初始化的 NSHost 对象。 然后,您可以使用此处显示并在reference post 中解释的流。

看看这个简单的代码;

let addr = "127.0.0.1"
let port = 4000

var host :NSHost = NSHost(address: addr)
var inp :NSInputStream?
var out :NSOutputStream?

NSStream.getStreamsToHost(host, port: port, inputStream: &inp, outputStream: &out)

let inputStream = inp!
let outputStream = out!
inputStream.open()
outputStream.open()

var readByte :UInt8 = 0
while inputStream.hasBytesAvailable 
    inputStream.read(&readByte, maxLength: 1)


// buffer is a UInt8 array containing bytes of the string "Jonathan Yaniv.".
outputStream.write(&buffer, maxLength: buffer.count)

在执行这个简单的代码之前,我启动了 ncat 以在我的终端中侦听端口 4000 并输入“你好!”并让套接字打开以进行通信。

Jonathans-MacBook-Air:~ johni$ ncat -l 4000
Hello !
Jonathan Yaniv.
Jonathans-MacBook-Air:~ johni$ 

启动代码后,您可以看到我在套接字关闭之前已收到字符串“Jonathan Yaniv.\n”到终端。

我希望这能让你们中的一些人感到头疼。 如果您有更多问题,请试一试,希望我能够回答。

& 符号在这篇文章中进行了解释。 (Reference to NSInputStream read use)

【讨论】:

请注意 getStreamsToHost(_:port:inputStream:outputStream:) 已被弃用。请改用 getStreamsToHostWithName("127.0.0.1", port: port, inputStream: &inp, outputStream: &out)。 上述评论的建议不存在了。使用 Stream.getStreamsToHost(withName: address, port: port, inputStream: &inp, outputStream: &out) 我很困惑(而且是一个完全的 Swift 新手)。 “NSStream.getStreamsToHost”、“Stream.getStreamsToHost”和“Stream.getStreamsToHost”都不适合我。我正在使用 Swift 4.0.3。

以上是关于在 Swift 中像在 Java 中一样使用套接字的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 中像在 Google 地图中一样获得持续的位置更新?

在 Swift 中像 Tab View Controller 一样滑动 uiView

循环在vue js中像在php foreach中获取html表

如何在 Swift 中像数组一样访问图像资源

Swift3 如何像在 android 中一样在 iOS 中实现底部工作表

我们可以像在 android asyncTask 中一样显示加载状态,直到我们在 swift 中使用 HTTP Post 请求得到响应