-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Dr. Brandon Wiley
committed
Sep 1, 2020
1 parent
c59d226
commit 0f7363e
Showing
5 changed files
with
208 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import Foundation | ||
import Network | ||
import Datable | ||
|
||
public class Connection | ||
{ | ||
var connection: NWConnection | ||
var connectLock = DispatchGroup() | ||
var readLock = DispatchGroup() | ||
var writeLock = DispatchGroup() | ||
|
||
public convenience init?(host: String, port: Int) | ||
{ | ||
let nwhost = NWEndpoint.Host(host) | ||
|
||
let port16 = UInt16(port) | ||
let nwport = NWEndpoint.Port(integerLiteral: port16) | ||
|
||
let nwconnection = NWConnection(host: nwhost, port: nwport, using: .tcp) | ||
|
||
self.init(connection: nwconnection) | ||
} | ||
|
||
init?(connection: NWConnection) | ||
{ | ||
self.connection = connection | ||
|
||
var success = false | ||
|
||
self.connectLock.enter() | ||
self.connection.stateUpdateHandler = | ||
{ | ||
(state) in | ||
|
||
switch state | ||
{ | ||
case .ready: | ||
success = true | ||
self.connectLock.leave() | ||
return | ||
case .cancelled: | ||
self.connectLock.leave() | ||
return | ||
case .failed(_): | ||
self.connectLock.leave() | ||
return | ||
default: | ||
return | ||
} | ||
} | ||
|
||
self.connection.start(queue: .global()) | ||
|
||
connectLock.wait() | ||
|
||
guard success else {return nil} | ||
} | ||
|
||
public func read(size: Int) -> Data? | ||
{ | ||
var result: Data? | ||
|
||
self.readLock.enter() | ||
self.connection.receive(minimumIncompleteLength: size, maximumLength: size) | ||
{ | ||
(maybeData, maybeContext, isComplete, maybeError) in | ||
|
||
guard maybeError == nil else | ||
{ | ||
self.readLock.leave() | ||
return | ||
} | ||
|
||
if let data = maybeData | ||
{ | ||
result = data | ||
} | ||
|
||
self.readLock.leave() | ||
} | ||
|
||
readLock.wait() | ||
|
||
return result | ||
} | ||
|
||
public func write(string: String) -> Bool | ||
{ | ||
let data = string.data | ||
return write(data: data) | ||
} | ||
|
||
public func write(data: Data) -> Bool | ||
{ | ||
var success = false | ||
|
||
self.writeLock.enter() | ||
self.connection.send(content: data, completion: NWConnection.SendCompletion.contentProcessed( | ||
{ | ||
(maybeError) in | ||
|
||
guard maybeError == nil else | ||
{ | ||
success = false | ||
self.writeLock.leave() | ||
return | ||
} | ||
|
||
success = true | ||
self.writeLock.leave() | ||
return | ||
})) | ||
|
||
self.writeLock.wait() | ||
|
||
return success | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// | ||
// Listener.swift | ||
// | ||
// | ||
// Created by Dr. Brandon Wiley on 8/31/20. | ||
// | ||
|
||
import Foundation | ||
import Network | ||
import Chord | ||
|
||
public class Listener | ||
{ | ||
let listener: NWListener | ||
let queue: BlockingQueue<Connection> = BlockingQueue<Connection>() | ||
let lock: DispatchGroup = DispatchGroup() | ||
|
||
public init?(port: Int) | ||
{ | ||
let port16 = UInt16(port) | ||
let nwport = NWEndpoint.Port(integerLiteral: port16) | ||
|
||
guard let listener = try? NWListener(using: .tcp, on: nwport) else {return nil} | ||
self.listener = listener | ||
|
||
self.listener.newConnectionHandler = | ||
{ | ||
nwconnection in | ||
|
||
guard let connection = Connection(connection: nwconnection) else {return} | ||
|
||
self.queue.enqueue(element: connection) | ||
} | ||
|
||
self.listener.start(queue: .global()) | ||
} | ||
|
||
public func accept() -> Connection | ||
{ | ||
return self.queue.dequeue() | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,47 @@ | ||
import XCTest | ||
import Foundation | ||
@testable import Transmission | ||
|
||
final class TransmissionTests: XCTestCase { | ||
func testExample() { | ||
// This is an example of a functional test case. | ||
// Use XCTAssert and related functions to verify your tests produce the correct | ||
// results. | ||
XCTAssertEqual(Transmission().text, "Hello, World!") | ||
final class TransmissionTests: XCTestCase | ||
{ | ||
public func testConnection() | ||
{ | ||
let lock = DispatchGroup() | ||
let queue = DispatchQueue(label: "testing") | ||
|
||
lock.enter() | ||
|
||
queue.async | ||
{ | ||
self.runServer(lock) | ||
} | ||
|
||
lock.wait() | ||
|
||
runClient() | ||
} | ||
|
||
func runServer(_ lock: DispatchGroup) | ||
{ | ||
guard let listener = Listener(port: 1234) else {return} | ||
lock.leave() | ||
|
||
static var allTests = [ | ||
("testExample", testExample), | ||
] | ||
let connection = listener.accept() | ||
let _ = connection.read(size: 4) | ||
let _ = connection.write(string: "back") | ||
} | ||
|
||
func runClient() | ||
{ | ||
let connection = Connection(host: "127.0.0.1", port: 1234) | ||
XCTAssertNotNil(connection) | ||
|
||
let writeResult = connection!.write(string: "test") | ||
XCTAssertTrue(writeResult) | ||
|
||
let result = connection!.read(size: 4) | ||
XCTAssertNotNil(result) | ||
|
||
XCTAssertEqual(result!, "back") | ||
} | ||
} |