Apple’s TCP sample code

This thread has been locked by a moderator.

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?

Up vote post of itang
6.5k views

Accepted Reply

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()

Replies

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"