Apple’s TCP sample code

This thread has been locked by a moderator; it no longer accepts new replies.

I want to see Apple’s TCP sample code, When I saw Apple’s UDP sample code - UDPEcho. But I does’t found it.

Do you know Apple’s TCP sample code like UDPEcho?

Answered by DTS Engineer in 360743022

I want to see Apple’s TCP sample code …

Apple platforms support many different TCP APIs. The TCPTransports sample code shows four of thsee APIs (

CFSocketStream
,
NSURLSessionStreamTask
, BSD Sockets, and
NWTCPConnection
).

The only remaining API is the Network framework, for which there isn’t a good official sample yet [1]. We are working on addressing that, but for the moment, I’ve pasted a tiny example in below, just to get your started.

If you have any further questions about any of these APIs, I’m happy to answer them.

Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] There’s nwcat, but it has a number of drawbacks, not least of which is that it’s a C sample.

import Foundation
import Network

class Main {

    init(hostName: String, port: Int) {
        let host = NWEndpoint.Host(hostName)
        let port = NWEndpoint.Port("\(port)")!
        self.connection = NWConnection(host: host, port: port, using: .tcp)
    }

    let connection: NWConnection

    func start() {
        NSLog("will start")
        self.connection.stateUpdateHandler = self.didChange(state:)
        self.startReceive()
        self.connection.start(queue: .main)
    }

    func stop() {
        self.connection.cancel()
        NSLog("did stop")
    }

    private func didChange(state: NWConnection.State) {
        switch state {
        case .setup:
            break
        case .waiting(let error):
            NSLog("is waiting: %@", "\(error)")
        case .preparing:
            break
        case .ready:
            break
        case .failed(let error):
            NSLog("did fail, error: %@", "\(error)")
            self.stop()
        case .cancelled:
            NSLog("was cancelled")
            self.stop()
        @unknown default:
            break
        }
    }

    private func startReceive() {
        self.connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { data, _, isDone, error in
            if let data = data, !data.isEmpty {
                NSLog("did receive, data: %@", data as NSData)
            }
            if let error = error {
                NSLog("did receive, error: %@", "\(error)")
                self.stop()
                return
            }
            if isDone {
                NSLog("did receive, EOF")
                self.stop()
                return
            }
            self.startReceive()
        }
    }

    func send(line: String) {
        let data = Data("\(line)\r\n".utf8)
        self.connection.send(content: data, completion: NWConnection.SendCompletion.contentProcessed { error in
            if let error = error {
                NSLog("did send, error: %@", "\(error)")
                self.stop()
            } else {
                NSLog("did send, data: %@", data as NSData)
            }
        })
    }

    static func run() -> Never {
        let m = Main(hostName: "127.0.0.1", port: 12345)
        m.start()

        let t = DispatchSource.makeTimerSource(queue: .main)
        var counter = 99
        t.setEventHandler {
            m.send(line: "\(counter) bottles of beer on the wall.")
            counter -= 1
            if counter == 0 {
                m.stop()
                exit(EXIT_SUCCESS)
            }
        }
        t.schedule(wallDeadline: .now() + 1.0, repeating: 1.0)
        t.activate()

        dispatchMain()
    }
}

Main.run()
Accepted Answer

I want to see Apple’s TCP sample code …

Apple platforms support many different TCP APIs. The TCPTransports sample code shows four of thsee APIs (

CFSocketStream
,
NSURLSessionStreamTask
, BSD Sockets, and
NWTCPConnection
).

The only remaining API is the Network framework, for which there isn’t a good official sample yet [1]. We are working on addressing that, but for the moment, I’ve pasted a tiny example in below, just to get your started.

If you have any further questions about any of these APIs, I’m happy to answer them.

Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

[1] There’s nwcat, but it has a number of drawbacks, not least of which is that it’s a C sample.

import Foundation
import Network

class Main {

    init(hostName: String, port: Int) {
        let host = NWEndpoint.Host(hostName)
        let port = NWEndpoint.Port("\(port)")!
        self.connection = NWConnection(host: host, port: port, using: .tcp)
    }

    let connection: NWConnection

    func start() {
        NSLog("will start")
        self.connection.stateUpdateHandler = self.didChange(state:)
        self.startReceive()
        self.connection.start(queue: .main)
    }

    func stop() {
        self.connection.cancel()
        NSLog("did stop")
    }

    private func didChange(state: NWConnection.State) {
        switch state {
        case .setup:
            break
        case .waiting(let error):
            NSLog("is waiting: %@", "\(error)")
        case .preparing:
            break
        case .ready:
            break
        case .failed(let error):
            NSLog("did fail, error: %@", "\(error)")
            self.stop()
        case .cancelled:
            NSLog("was cancelled")
            self.stop()
        @unknown default:
            break
        }
    }

    private func startReceive() {
        self.connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { data, _, isDone, error in
            if let data = data, !data.isEmpty {
                NSLog("did receive, data: %@", data as NSData)
            }
            if let error = error {
                NSLog("did receive, error: %@", "\(error)")
                self.stop()
                return
            }
            if isDone {
                NSLog("did receive, EOF")
                self.stop()
                return
            }
            self.startReceive()
        }
    }

    func send(line: String) {
        let data = Data("\(line)\r\n".utf8)
        self.connection.send(content: data, completion: NWConnection.SendCompletion.contentProcessed { error in
            if let error = error {
                NSLog("did send, error: %@", "\(error)")
                self.stop()
            } else {
                NSLog("did send, data: %@", data as NSData)
            }
        })
    }

    static func run() -> Never {
        let m = Main(hostName: "127.0.0.1", port: 12345)
        m.start()

        let t = DispatchSource.makeTimerSource(queue: .main)
        var counter = 99
        t.setEventHandler {
            m.send(line: "\(counter) bottles of beer on the wall.")
            counter -= 1
            if counter == 0 {
                m.stop()
                exit(EXIT_SUCCESS)
            }
        }
        t.schedule(wallDeadline: .now() + 1.0, repeating: 1.0)
        t.activate()

        dispatchMain()
    }
}

Main.run()

Thank you!
This is Swift sample code. I haven't started to learn Swift. Have Objective-C edition ?

Have Objective-C edition ?

Network framework has no Objective-C API. Your choices are:

  • Swift, as shown by my snippet above

  • Plain ol’ C, as shown by nwcat

Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Ok, thanks.

Thanks for the example: using the command line example can read the NMEA 0183 traffic.

However, I cannot figure out how to set ye DispatchQueues or tasks when staring it from SwiftUI (initially on macOS) . Any ideas, the error message is below:

==

2021-01-08 17:14:48.505411+0200 Display0183 M.[33431:2246222] [general] Attempting to perform block on main runloop, but the main thread has exited. This message will only log once. Break on CFRunLoopErrorMainThreadHasExited to debug.

2021-01-08 17:14:48.505517+0200 Display0183 M.[33431:2246222] [general] Attempting to wake up main runloop, but the main thread as exited. This message will only log once. Break on CFRunLoopErrorMainThreadHasExited to debug.

Assertion failed: (NSViewIsCurrentlyBuildingLayerTreeForDisplay() != currentlyBuildingLayerTree), function NSViewSetCurrentlyBuildingLayerTreeForDisplay, file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-2022.20.119/AppKit.subproj/NSView.m, line 13401.
I recommend that you start a new thread for this. Whatever problem you’re having, it’s unlikely to be related to the overarching issue covered by this thread.

Tag it with Network so that I see it.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"

Hi Folks,

Whenever I try to make the connection I got the following message :

[connection] nw_socket_handle_socket_event [C1:1] Socket SO_ERROR [61: Connection refused] 2022-09-20 12:26:27.695439+0530 NetworkSample[6165:1970925] [connection] nw_read_request_report [C1] Receive failed with error "Connection refused" 2022-09-20 12:26:27.711315+0530 NetworkSample[6165:1970930] did receive, error: POSIXErrorCode(rawValue: 61): Connection refused 2022-09-20 12:26:27.711474+0530 NetworkSample[6165:1970930] did stop 2022-09-20 12:26:32.685079+0530 NetworkSample[6165:1970930] is waiting: POSIXErrorCode(rawValue: 61): Connection refused 2022-09-20 12:26:37.971629+0530 NetworkSample[6165:1970930] was cancelled 2022-09-20 12:26:39.410259+0530 NetworkSample[6165:1970930] did stop 2022-09-20 12:26:39.410312+0530 NetworkSample[6165:1970926] [connection] [C1 192.168.1.17:8080 tcp, attribution: developer] is already cancelled, ignoring cancel

I am using that code snippets

class Main {

  init(hostName: String, port: Int) {
    let host = NWEndpoint.Host(hostName)
    let port = NWEndpoint.Port("\(port)")!
    self.connection = NWConnection(host: host, port: port, using: .tcp)
  }

  let connection: NWConnection

  func start() {
    NSLog("will start")
    self.connection.stateUpdateHandler = self.didChange(state:)
    self.startReceive()
    self.connection.start(queue: .main)
  }

  func stop() {
    self.connection.cancel()
    NSLog("did stop")
  }

  private func didChange(state: NWConnection.State) {
    switch state {
    case .setup:
      break
    case .waiting(let error):
      NSLog("is waiting: %@", "\(error)")
    case .preparing:
      break
    case .ready:
      break
    case .failed(let error):
      NSLog("did fail, error: %@", "\(error)")
      self.stop()
    case .cancelled:
      NSLog("was cancelled")
      self.stop()
    @unknown default:
      break
    }
  }

  private func startReceive() {
    self.connection.receive(minimumIncompleteLength: 1, maximumLength: 65536) { data, _, isDone, error in
      if let data = data, !data.isEmpty {
        NSLog("did receive, data: %@", data as NSData)
      }
      if let error = error {
        NSLog("did receive, error: %@", "\(error)")
        self.stop()
        return
      }
      if isDone {
        NSLog("did receive, EOF")
        self.stop()
        return
      }
      self.startReceive()
    }
  }

  func send(line: String) {
    let data = Data("\(line)\r\n".utf8)
    self.connection.send(content: data, completion: NWConnection.SendCompletion.contentProcessed { error in
      if let error = error {
        NSLog("did send, error: %@", "\(error)")
        self.stop()
      } else {
        NSLog("did send, data: %@", data as NSData)
      }
    })
  }

  static func run() -> Never {
    
    let m = Main(hostName: "192.168.1.17", port: 8080)
    m.start()

    let t = DispatchSource.makeTimerSource(queue: .main)
    var counter = 99
    t.setEventHandler {
      m.send(line: "\(counter) bottles of beer on the wall.")
      counter -= 1
      if counter == 0 {
        m.stop()
        exit(EXIT_SUCCESS)
      }
    }
    t.schedule(wallDeadline: .now() + 1.0, repeating: 1.0)
    t.activate()
    

    dispatchMain()
  }
}



I recommend that you start a new thread for this. I’m going to lock this thread because I don’t want it to become the one super mega thread that covers all networking issues.

Tag your new thread with Network so that I see it. Also, feel free to reference back to this thread if there’s something relevant that you want to call out.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Apple’s TCP sample code
 
 
Q