在使用NWConnection API的iOS应用程序中未通过TCP接收消息



我有一个iOS客户端应用程序,它通过TCP创建NWConnection。

connection = NWConnection(host: hostTCP, port: portTCP, using: .tcp)
connection?.stateUpdateHandler =
{ [self] (newState) in
print("This is stateUpdateHandler:")
switch (newState)
{
case .ready:
print("State: Readyn")
self.sendTCP(messageToTCP)
self.receiveTCP()
case .setup:
print("State: Setupn")
case .cancelled:
print("State: Cancelledn")
case .preparing:
print("State: Preparingn")
default:
print("ERROR! State not definedn")
}
}
print("connectToTCP: Connection to server startedn")
connection?.start(queue: .global())

, receiveTCP()函数如下:

func receiveTCP()
{
connection?.receiveMessage
{ (data, context, isComplete, error) in
if (isComplete)
{
print("Receive is complete")
if (data != nil)
{
let backToString = String(decoding: data!, as: UTF8.self)
print("Received message: (backToString)")
}
else
{
print("Data == nil")
}
}
else
{
self.receiveTCP()
}
}
}

我使用命令行工具作为服务器应用程序在我的macBook上运行,它侦听传入连接并发送/接收消息。从iOS客户端应用程序发送消息工作正常,但接收不工作。此外,客户端应用程序工作(发送和接收)在UDP上很好。我在这里做错了什么吗?

在Apple文档https://developer.apple.com/documentation/network/nwconnection/3020638-receivemessage

其提到的

接收消息允许您处理完整的数据报或应用层消息,而无需重构流。如果您使用UDP,则接收消息将传递单个数据报。如果你请求在一个协议上接收一个消息,而这个协议是一个无界字节流,比如TCP或TLS,请注意,在流被对等端关闭之前,它不会传递任何数据。

这是什么意思"如果你请求接收一个协议上的消息,否则它是一个无界字节流,如TCP或TLS,请注意,这将不会传递任何数据,直到该流被对等端关闭"?

有没有人知道一个简单的TCP的iOS设备的例子,使用NWFramework发送和接收字符串数据的服务器?

TCP是一个基于流的协议。连接仅仅是两个字节流——send &接收。这里没有"消息"的概念;TCP中固有的。您的应用程序需要对流施加一些框架以从中提取结构。例如:你可以发送"hellon","Worldn","testn"作为对send的三个独立呼叫,但所有这些数据都可以在一个数据包中发送到目的地;TCP栈试图优化网络利用率,发送单个较大的数据包比发送多个较小的数据包更有效。

同样,如果数据量超过网络的最大传输单元(MTU),则传递给send的大量数据可能以多个数据包的形式发送。如果遇到MTU较小的链路,通过Internet发送的数据甚至可以被分割成更小的数据包。TCP所保证的是发送的字节将按照发送的顺序传递。不能保证有多少数据包到达。

这是什么意思"如果你请求接收一个协议上的消息,否则它是一个无界字节流,如TCP或TLS,注意这将不会传递任何数据,直到流被对等端关闭"?

表示在服务器关闭TCP连接之前,您将不会收到任何消息。如果你的服务器代码在发送响应后没有关闭连接,那么receiveMessage将不会完成。您可以使用receive(minimumIncompleteLength:maximumLength:completion:)以"块"的形式接收响应。然后,您需要重新组装这些并提取您的消息(例如,您的消息可能由新行n终止-您将查看数据中的新行字符,以便将接收到的数据拆分为离散的消息。

Apple提供NWProtocolFramer协议,允许您创建代码来解析来自TCP流的消息。您实现符合NWProtocolFramerImplementation的代码,并对提供的NWProtocolFramer.Instance进行操作,以从流中提取消息并将消息编码回字节流。

最新更新