Latest 1.0.0
Homepage https://github.com/Meniny/SecureSocket
License MIT
Platforms osx 10.11, ios 10.0, watchos 2.0, tvos 9.0, requires ARC
Authors

SecureSocket

VersionAuthorBuild PassingSwift
PlatformsMIT
CocoapodsCarthageSPM

What’s this?

SecureSocket is a generic low level socket framework written in Swift.

SecureSocket works on iOS, macOS, and Linux.

Requirements

  • iOS 10.0+
  • macOS 10.11+
  • watchOS 2.0+
  • tvOS 9.0+
  • Xcode 8.3.2+ with Swift 3.1.1+
  • One of the Swift Open Source toolchains listed above

Installation

CocoaPods

platform :ios, '10.0'

target 'YOURTARGETNAME' do
    use_frameworks!
    pod 'SecureSocket'
end

Example

import Foundation
import Socket
import Dispatch

class EchoServer {

    static let quitCommand: String = "QUIT"
    static let shutdownCommand: String = "SHUTDOWN"
    static let bufferSize = 4096

    let port: Int
    var listenSocket: Socket? = nil
    var continueRunning = true
    var connectedSockets = [Int32: Socket]()
    let socketLockQueue = DispatchQueue(label: "com.ibm.serverSwift.socketLockQueue")

    init(port: Int) {
        self.port = port
    }

    deinit {
        // Close all open sockets...
        for socket in connectedSockets.values {
            socket.close()
        }
        self.listenSocket?.close()
    }

    func run() {

        let queue = DispatchQueue.global(qos: .userInteractive)

        queue.async { [unowned self] in

            do {
                // Create an IPV6 socket...
                try self.listenSocket = Socket.create(family: .inet6)

                guard let socket = self.listenSocket else {

                    print("Unable to unwrap socket...")
                    return
                }

                try socket.listen(on: self.port)

                print("Listening on port: (socket.listeningPort)")

                repeat {
                    let newSocket = try socket.acceptClientConnection()

                    print("Accepted connection from: (newSocket.remoteHostname) on port (newSocket.remotePort)")
                    print("Socket Signature: (newSocket.signature?.description)")

                    self.addNewConnection(socket: newSocket)

                } while self.continueRunning

            }
            catch let error {
                guard let socketError = error as? Socket.Error else {
                    print("Unexpected error...")
                    return
                }

                if self.continueRunning {

                    print("Error reported:n (socketError.description)")

                }
            }
        }
        dispatchMain()
    }

    func addNewConnection(socket: Socket) {

        // Add the new socket to the list of connected sockets...
        socketLockQueue.sync { [unowned self, socket] in
            self.connectedSockets[socket.socketfd] = socket
        }

        // Get the global concurrent queue...
        let queue = DispatchQueue.global(qos: .default)

        // Create the run loop work item and dispatch to the default priority global queue...
        queue.async { [unowned self, socket] in

            var shouldKeepRunning = true

            var readData = Data(capacity: EchoServer.bufferSize)

            do {
                // Write the welcome string...
                try socket.write(from: "Hello, type 'QUIT' to end sessionnor 'SHUTDOWN' to stop server.n")

                repeat {
                    let bytesRead = try socket.read(into: &readData)

                    if bytesRead > 0 {
                        guard let response = String(data: readData, encoding: .utf8) else {

                            print("Error decoding response...")
                            readData.count = 0
                            break
                        }
                        if response.hasPrefix(EchoServer.shutdownCommand) {

                            print("Shutdown requested by connection at (socket.remoteHostname):(socket.remotePort)")

                            // Shut things down...
                            self.shutdownServer()

                            return
                        }
                        print("Server received from connection at (socket.remoteHostname):(socket.remotePort): (response) ")
                        let reply = "Server response: n(response)n"
                        try socket.write(from: reply)

                        if (response.uppercased().hasPrefix(EchoServer.quitCommand) || response.uppercased().hasPrefix(EchoServer.shutdownCommand)) &&
                            (!response.hasPrefix(EchoServer.quitCommand) && !response.hasPrefix(EchoServer.shutdownCommand)) {

                            try socket.write(from: "If you want to QUIT or SHUTDOWN, please type the name in all caps. 😃n")
                        }

                        if response.hasPrefix(EchoServer.quitCommand) || response.hasSuffix(EchoServer.quitCommand) {

                            shouldKeepRunning = false
                        }
                    }

                    if bytesRead == 0 {

                        shouldKeepRunning = false
                        break
                    }

                    readData.count = 0

                } while shouldKeepRunning

                print("Socket: (socket.remoteHostname):(socket.remotePort) closed...")
                socket.close()

                self.socketLockQueue.sync { [unowned self, socket] in
                    self.connectedSockets[socket.socketfd] = nil
                }

            }
            catch let error {
                guard let socketError = error as? Socket.Error else {
                    print("Unexpected error by connection at (socket.remoteHostname):(socket.remotePort)...")
                    return
                }
                if self.continueRunning {
                    print("Error reported by connection at (socket.remoteHostname):(socket.remotePort):n (socketError.description)")
                }
            }
        }
    }

    func shutdownServer() {
        print("nShutdown in progress...")
        continueRunning = false

        // Close all open sockets...
        for socket in connectedSockets.values {
            socket.close()
        }

        listenSocket?.close()

        DispatchQueue.main.sync {
            exit(0)
        }
    }
}

let port = 1337
let server = EchoServer(port: port)
print("Swift Echo Server Sample")
print("Connect with a command line window by entering 'telnet 127.0.0.1 (port)'")

server.run()

Latest podspec

{
    "name": "SecureSocket",
    "module_name": "SecureSocket",
    "version": "1.0.0",
    "summary": "SecureSocket is a generic low level socket framework written in Swift.",
    "homepage": "https://github.com/Meniny/SecureSocket",
    "license": "MIT",
    "authors": {
        "Meniny": "[email protected]"
    },
    "source": {
        "git": "https://github.com/Meniny/SecureSocket.git",
        "tag": "1.0.0"
    },
    "social_media_url": "http://meniny.cn/",
    "requires_arc": true,
    "platforms": {
        "osx": "10.11",
        "ios": "10.0",
        "watchos": "2.0",
        "tvos": "9.0"
    },
    "source_files": "Sources/*.swift",
    "pod_target_xcconfig": {
        "SWIFT_VERSION": "3.1.1"
    },
    "pushed_with_swift_version": "3.1.1"
}

Pin It on Pinterest

Share This