Skip to content

Instantly share code, notes, and snippets.

@hotpaw2
Last active January 3, 2023 17:06
Show Gist options
  • Save hotpaw2/7c37c2ccf10576191979fe1eca203111 to your computer and use it in GitHub Desktop.
Save hotpaw2/7c37c2ccf10576191979fe1eca203111 to your computer and use it in GitHub Desktop.
// MyURLStreamTask.swift
// Demonstrates using an NSURLSessionStreamTask to implement a bidirectional TCP socket connection
//
// by [email protected] 2017-03-07
// distribution: BSD 2-clause
//
import Foundation
class MyURLStreamTask {
let session = URLSession(configuration: .default)
var hostIPString = "127.0.0.1" // or set to whatever
let port = 80 // as needed
var task : URLSessionStreamTask? = nil
var socketRunning = false
var status = String()
func startNetworkStreams() {
// create a URLSessionStreamTask
task = session.streamTask(withHostName: hostIPString, port: port)
if task != nil {
self.task?.resume() // start task running
socketRunning = true
status = ""
}
}
var writeCounter = 0
func sendCommand(_ flag : Int, dataBuffer : [Byte], len : Int ) { // write data to socket
guard socketRunning else { return }
let data = Data(bytes: dataBuffer, count: len)
let timeout = TimeInterval(2.0)
task?.write(data, timeout: timeout, completionHandler:
{ (err: Error?) -> Void in
if err == nil {
self.writeCounter += 1
} else {
self.status = err!.localizedDescription // display somewhere when error handling
self.close()
socketRunning = true
}
} )
}
var requestedBytes = 0
func myRead(bytes : Int) { // call myRead periodically as needed
guard socketRunning else { return }
requestedBytes = bytes
let minBytes = 1
let maxBytes = bytes
let timeout = TimeInterval(2.0)
task?.readData(ofMinLength: minBytes, // read from socket
maxLength: maxBytes,
timeout: timeout, completionHandler:
{ (data: Data?, flag: Bool, err: Error?) -> Void in
if err == nil {
if let d = data {
let byteCount = d.count
var _ = d.withUnsafeBytes{ (buffer: UnsafePointer<UInt8>) -> Int in
//
// copy data buffer or call a delegate return function here
//
return 0
}
self.requestedBytes -= byteCount
if self.requestedBytes > 0 {
// call on main thread for low bandwidth needs
self.myRead(bytes: self.requestedBytes)
}
}
} else {
self.status = err!.localizedDescription // for error reporting
self.close()
socketRunning = true
} } )
}
func close() {
if task != nil && socketRunning {
task!.closeRead()
task!.closeWrite()
}
socketRunning = false
}
} // end of class MyURLStreamTask
// eof
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment