 
             strong_self.state = .Connecting
 
-            let socketDescriptor = Darwin.socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
-            guard socketDescriptor >= 0 else {
-                let error = Errno(rawValue: errno)!
-                close(socketDescriptor)
-                callback(Result.Failure(error))
-                return
-            }
-
-            var addr = address.to_sockaddr(port: port)
-
-            let result = Darwin.connect(socketDescriptor, &addr, socklen_t(sizeof(sockaddr)))
-            guard result == 0 else {
-                let error = Errno(rawValue: errno)!
-                close(socketDescriptor)
-                strong_self.state = .Unconnected
-                callback(Result.Failure(error))
-                return
-            }
-
-            let channel = dispatch_io_create(DISPATCH_IO_STREAM, socketDescriptor, queue) {
-                (error) in
-
-                guard let strong_self = self else {
-                    return
-                }
-
-                strong_self.handleDisconnect()
-            }
-
-            dispatch_io_set_low_water(channel, 0)
-
+            let socket = try! Socket.TCP()
+
+            try! socket.connect(address, port: port)
+
+            strong_self.socket = socket
             strong_self.state = .Connected
-            strong_self.channel = channel
-            strong_self.socketDescriptor = socketDescriptor
-
-            strong_self.startReading()
 
             callback(Result.Success())
         }

    }

    public private(set) var queue: dispatch_queue_t!
    public private(set) var socketDescriptor: Int32!
    public private(set) var channel: dispatch_io_t!
    public private(set) var state: State = .Unconnected {
        didSet {
            stateChangeCallback?(oldValue, state)
        }
    }
    private var disconnectCallback: (Result <Void> -> Void)?


    public init(address: Address, port: UInt16) throws {
        self.address = address

    // MARK: -

    public func write(data: DispatchData <Void>, callback: Result <Void> -> Void) {
        precondition(state == .Connected)
        dispatch_io_write(channel, 0, data.data, queue) {
            (done, data, error) in
            guard error == 0 else {
                callback(Result.Failure(Errno(rawValue: error)!))
                return
            }
            callback(Result.Success())
        }
    }

// mark: -

    private func stateChanged(old old: State, new: State) {
        stateChangeCallback?(old, new)

        switch (old, new) {
            case (_, .Connected):

                if queue == nil {
                    let queueAttribute = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, qos, 0)
                    queue = dispatch_queue_create("io.schwa.SwiftIO.UDP.receiveQueue", queueAttribute)
                }

                let channel = dispatch_io_create(DISPATCH_IO_STREAM, socket.descriptor, queue) {
                    [weak self] (error) in

                    guard let strong_self = self else {
                        return
                    }

                    try! strong_self.handleDisconnect()
                }
                dispatch_io_set_low_water(channel, 0)
                self.channel = channel
                startReading()
            default:
                break
        }
    }

    /// Callback might be called 0 or more times.
    private func startReading() {
