带有 TCP 的 Swift 网络框架

Sas*_*kin 7 network-programming tcp ios swift

我正在使用 Swift Network 框架制作一个简单的测试应用程序。一台服务器,一台客户端(都是iOS模拟器),并成功建立了它们之间的tcp连接。我正在尝试发送一系列短消息。

服务器正在发送由 1 到 999 的自然数组成的字符串。每个数字都作为单独的数据发送,isCompletecontentContext 的默认值分别为true.defaultMessage

var count = 0

func send(data: Data) {
    self.connection.send(content: data, completion: .contentProcessed( { error in
        if let error = error {
            self.connectionDidFail(error: error)
            return
        }
        self.count += 1
        let newData = "\(self.count)".data(using: .utf8)!
        if self.count < 1000 {
            self.send(data: newData)
        }
        print("connection \(self.id) did send, data: \(newData as NSData)")
    }))
}
Run Code Online (Sandbox Code Playgroud)

客户正在接收他们...

private func setupReceive() {
    nwConnection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { (data, contentContext, isComplete, error) in
        if let data = data, !data.isEmpty {
            print("isComplete: \(isComplete)")
            print("isFinal: \(contentContext.isFinal)")
            let message = String(data: data, encoding: .utf8)
            print("connection did receive, data: \(data as NSData) string: \(message ?? "-" )")
        }
        if let error = error {
            self.connectionDidFail(error: error)
        } else {
            self.setupReceive()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

……但有什么不对。有些消息看起来像是它们的字节粘在一起(例如,可以像单个消息“2345”一样接收连续的消息“2”、“3”、“4”、“5”)

对于所有收到的消息,isComplete等于false 并且contentContext属性isFinal等于true,而.defaultMessage.isFinal应该等于false

现在,我被困住了。我是否只是使用了错误的参数(我尝试了各种组合,但似乎没有一个对我有用)?NWConnection 在发送消息时是否会可怕地更改消息?

如何发送一系列单独的消息?

jms*_*jms 0

我对这个框架不熟悉Network。但从阅读文档来看,似乎是直接使用传输层来传输消息。

如果没有应用程序层协议,客户端可能无法区分不同的消息。例如,使用http作为您的应用程序协议在请求中具有不同的参数来识别它是否是完整的消息(内容长度,内容编码,传输编码等...)(希望专家能够确认这一点)

您可以定义自己的简单协议,以便可以在客户端进行解码。例如,您可以用 包装每条消息并<Message>your-message</Message>使用它来识别客户端上的不同消息(在此过程中您将面临如此简单的事情的一些缺点)

开发自定义协议时需要考虑很多事情。如果您认真对待这个主题,最好阅读一些相关内容。

进一步阅读后,似乎提供了以下接收:

final func receiveMessage(completion: @escaping (Data?, NWConnection.ContentContext?, Bool, NWError?) -> Void)
Run Code Online (Sandbox Code Playgroud)

...能够读取完整的数据。讨论部分将提供有关传输类型影响和所需的框架逻辑的一些有价值的见解。