Posts

Post marked as solved
4 Replies
751 Views
I have a device that my app needs to communicate with over TCP. It uses a simple communication protocol that separates messages with a single character delimiter. I have been attempting to use the NWProtocolFramer implementation attached to my connection and am having problems when messages are across TCP packets.In my case, once I've sent the command to retrieve the messages, the first item the device sends back is the number of expected messages. I then retrieve this number and then in a loop attempt to retrieve the remaining messages. The pseudo code looks like this:let command = opCode.commandString.data(using: .utf8) connection.send(content: command, completion: .contentProcessed({ (error) in // handle error })) connection.receiveMessage(completion: { (content, context, isComplete, error) in let numberOfMessages = Int(String(data: content!, encoding: .utf8)) for count in 0..<numberOfMessages { connection.receiveMessage(completion: { (content, context, isComplete, error) in let message = String(data: content!, encoding: .utf8) // process message }) } })The NWProtocolFramer.handleInput method psuedo code looks like this (thanks to Quinn's post : https://forums.developer.apple.com/thread/118686func handleInput { while true { var didFindDelimiter = false var countBeforeDelimiter = 0 let parseResult = framer.parseInput(minimumIncompleteLength: 1, maximumLength: 65535) { … search the data for the delimiter then set up `didFindDelimiter` and `countBeforeDelimiter` … return 0 } guard parseResult, didFindDelimiter || countBeforeDelimiter != 0 else { // Nothing to deliver right now. return 0 } let didDeliver = framer.deliverInputNoCopy(length: countBeforeDelimiter, message: …, isComplete: didFindDelimiter) guard didDeliver else { return 0 } if didFindDelimiter { let _ = framer.parseInput(minimumIncompleteLength: 1, maximumLength: 65535) { (buffer, isComplete) -> Int in // move the buffer pointer down by 1 to discard the delimiter return 1 } } } }This works succssfully if all messages appear within a single TCP packet, but I have a situation where the messages go across the TCP packets as follows:Total number of messages expected: 78Packet 1: data length: 1514 bytes, contains 54 messagesPacket 2: data length: 749 bytes, contains 24 messagesThe handleInput method parses 53 messages and sends them back to the connection.receiveMessage. The 54th message though is only partially contained in the input buffer (cannot see its delimiter in the current input buffer) and so the handleInput does not send anything back (ie didFindDelimiter is always false).Essentially, the handleInput is in a continuous loop and the connection.recieveMessage just sits and waits and the remaining (1 + 24 messages) are not processed and essentially this thread is stuck.How should I handle this situation? a) How do I ask for the next TCP packet to appear in the inputBuffer, orb) Should I send back an incomplete message and somehow append the results togetherAny advice or guidance here would be much appreciated.Kind regardsDoug
Posted Last updated
.