Asynchronous non-blocking io with syncronous API. No callbacks.
.package(url: "https://github.com/swiftstack/aio.git", .branch("dev"))
Zero-cost socket abstraction designed for cooperative multitasking.
You can find this code and more in examples.
let socket = try Socket()
import Async
import Network
async {
let socket = try Socket()
// use non-blocking api
}
loop.run()
let hello = [UInt8]("Hello, World!".utf8)
let empty = [UInt8](repeating: 0, count: hello.count + 1)
async {
let socket = try Socket()
.bind(to: "127.0.0.1", port: 1111)
.listen()
let client = try socket.accept()
_ = try client.send(bytes: hello)
}
async {
let socket = try Socket()
.connect(to: "127.0.0.1", port: 1111)
var buffer = empty
_ = try socket.receive(to: &buffer)
}
let udpServerAddress = try Socket.Address("127.0.0.1", port: 2222)
async {
let socket = try Socket(type: .datagram)
.bind(to: udpServerAddress)
var buffer = empty
var client: Socket.Address? = nil
_ = try socket.receive(to: &buffer, from: &client)
_ = try socket.send(bytes: hello, to: client!)
}
async {
let socket = try Socket(type: .datagram)
var buffer = empty
_ = try socket.send(bytes: hello, to: udpServerAddress)
_ = try socket.receive(to: &buffer)
}
async {
let socket = try Socket(family: .inet6)
.bind(to: "::1", port: 3333)
.listen()
let client = try socket.accept()
_ = try client.send(bytes: hello)
}
async {
let socket = try Socket(family: .inet6)
.connect(to: "::1", port: 3333)
var buffer = empty
_ = try socket.receive(to: &buffer)
}
#if os(Linux)
let type: Socket.SocketType = .sequenced
#else
let type: Socket.SocketType = .stream
#endif
unlink("/tmp/socketexample.sock")
async {
let socket = try Socket(family: .unix, type: type)
.bind(to: "/tmp/socketexample.sock")
.listen()
let client = try socket.accept()
_ = try client.send(bytes: hello)
}
async {
let socket = try Socket(family: .unix, type: type)
.connect(to: "/tmp/socketexample.sock")
var buffer = empty
_ = try socket.receive(to: &buffer)
}
final class Socket {
enum Family {
case inet, inet6, unspecified, unix
}
enum SocketType {
case stream, datagram, sequenced
}
enum Address {
init(_: String, port: UInt16? = nil) throws
init(ip4: String, port: UInt16) throws
init(ip6: String, port: UInt16) throws
init(unix: String) throws
}
init(family: Family = .tcp, type: SocketType = .stream) throws
func bind(to: Address) throws -> Socket
func listen() throws -> Socket
func accept(deadline: Time = .distantFuture) throws -> Socket
func connect(to: Address, deadline: Time = .distantFuture) throws -> Socket
func close() throws
func send(bytes: UnsafeRawPointer, count: Int, deadline: Time = .distantFuture) throws -> Int
func send(bytes: UnsafeRawPointer, count: Int, to: Address, deadline: Time = .distantFuture) throws -> Int
func receive(to: UnsafeMutableRawPointer, count: Int, deadline: Time = .distantFuture) throws -> Int
func receive(to: UnsafeMutableRawPointer, count: Int, from: inout Address?, deadline: Time = .distantFuture) throws -> Int
}
extension Socket {
func bind(to: String, port: UInt16) throws -> Socket
func bind(to: String) throws -> Socket
func connect(to: String, port: UInt16, deadline: Time = .distantFuture) throws -> Socket
func connect(to: String, deadline: Time = .distantFuture) throws -> Socket
func send(bytes: [UInt8], deadline: Time = .distantFuture) throws -> Int
func send(bytes: [UInt8], to: Address, deadline: Time = .distantFuture) throws -> Int
func receive(to: inout [UInt8], deadline: Time = .distantFuture) throws -> Int
func receive(to: inout [UInt8], from: inout Address?, deadline: Time = .distantFuture) throws -> Int
}