Network framework send file using TCP protocol

I am able to send json data between NWConnection and NW Listener. I need help to send photo or any file to each other. I am using TCP protocol for data transfer. Please let me know how can I send any file.

Thank You

I need help to send photo or any file to each other. I am using TCP protocol for data transfer.

Okay, if you want to use TCP for this there are a few things to be aware of....

  1. You will need to break your file or photo data down into something that can be consumed by a TCP connection, and for this it would be a large chunk of Data, or NSData, so the hex bytes can be sent over the wire.

  2. TCP has transmission limits that are usually set to around 64K (65535 bytes), so if your file's bytes are larger than this then they will need to be split up and sent in chunks and reassembled on the other end.

  3. Due to the transmission size in #2 you will need to define a way to split up and reassemble your file so it does not become corrupted. You can create a basic TLV framing protocol to do this, or work out some other type of frame tagging mechanism in your code to keep track of these details.

  4. Lastly, and this is the big one, there is no guarantee that if your receiving connection calls to read x bytes, that you will receive exactly x bytes from the kernel. You may only get a partial read, and for this reason you will need to further keep track of how your data is transmitted and reassembled.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

I am using below function from NWConnection and I am able to send 5MB photo file. in Receive func maximum length I am giving MemoryLayout.size   final public func send(content: Data?, contentContext: NWConnection.ContentContext = .defaultMessage, isComplete: Bool = true, completion: NWConnection.SendCompletion) 

     self.nwConnection.receive(minimumIncompleteLength: MemoryLayout.size, maximumLength: MemoryLayout.size) { (sizePrefixData, contentContext , isComplete, error) in {

}

   func send(data: Data)    {      let sizePrefix = withUnsafeBytes(of: UInt32(data.count).bigEndian) { Data($0) }      self.nwConnection.batch {        self.nwConnection.send(content: sizePrefix,  completion: .contentProcessed( { error in          if let error = error {            self.delegate?.connectionError(connection: self, error: error)            return          }        }))                self.nwConnection.send(content: data, completion: .contentProcessed( { error in          if let error = error {            self.delegate?.connectionError(connection: self, error: error)            return          }        }))      }    }

I am able to receive 5MB photo file in single call back. That's means Network framework are splitting up and sending chunks are also assembled on receiver end gives? Can please explain more on that. Thanks in advance.

I am able to receive 5MB photo file in single call back. That's means Network framework are splitting up and sending chunks are also assembled on receiver end gives? Can please explain more on that.

That's great. I cannot exactly tell what is happening here because your code is a bit scrambled but it looks like you may be doing a batch send and then waiting for the callback and then possibly sending again? Not sure, but I am glad you did not have to go the framing route to approach this.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

I wanted to post an update to my framing recommendation yesterday. First I wanted to mention that my solution will work, but it is way over-engineering the problem you are trying to solve. Next, I suggest ignoring the transmission limits that I mentioned and try to do three simple things:

  1. Convert your file into Data and get the size. Append the size to the front of your bytes you are about to transmit, or optionally just sent it as a first packet. Optionally, take a hash of your file data and append it to the tail end of the data, or just send it as a last packet in the transmission.
  2. On the receiving end, let TCP transmit everything over without a framer.
  3. On the receiving side, once you start receiving data, peel off the size from the start of data so you know this is the size you need. Collect the rest of the data until you get to your hash and then calculate the hash of the received data to make sure you have received all of the data for the file.
Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Network framework send file using TCP protocol
 
 
Q