Skip to content

Instantly share code, notes, and snippets.

@loganwright
Created June 29, 2016 18:57
Show Gist options
  • Save loganwright/23430e65e17ca8f7ed8a0e380ecb188e to your computer and use it in GitHub Desktop.
Save loganwright/23430e65e17ca8f7ed8a0e380ecb188e to your computer and use it in GitHub Desktop.
Foundation Server - [WIP]
// http://stackoverflow.com/a/33729691/2611971
public class FoundationServer {
public static func listen(port: Int) {
let sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if sock_fd == -1 {
perror("Failure: creating socket")
exit(EXIT_FAILURE)
}
var sock_opt_on = Int32(1)
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &sock_opt_on, socklen_t(sizeofValue(sock_opt_on)))
var server_addr = sockaddr_in()
let server_addr_size = socklen_t(sizeofValue(server_addr))
server_addr.sin_len = UInt8(server_addr_size)
server_addr.sin_family = sa_family_t(AF_INET) // chooses IPv4
server_addr.sin_port = UInt16(port).bigEndian // chooses the port
let bind_server = withUnsafePointer(&server_addr) {
bind(sock_fd, UnsafePointer($0), server_addr_size)
}
if bind_server == -1 {
perror("Failure: binding port")
exit(EXIT_FAILURE)
}
if Foundation.listen(sock_fd, 5) == -1 {
exit(EXIT_FAILURE)
}
var client_addr = sockaddr_storage()
var client_addr_len = socklen_t(sizeofValue(client_addr))
let client_fd = withUnsafeMutablePointer(&client_addr) {
accept(sock_fd, UnsafeMutablePointer($0), &client_addr_len)
}
if client_fd == -1 {
perror("Failure: accepting connection")
exit(EXIT_FAILURE);
}
let inputStream = NSInputStream()
let fileDescriptor = NSNumber(value: client_fd)
inputStream.setProperty(fileDescriptor, forKey: (kCFStreamPropertySocketNativeHandle as NSString) as String)
inputStream.open()
var buff_rcvd = Bytes(repeating: 0, count: 1024)
let bytesRead = read(client_fd, &buff_rcvd, 1024)
inputStream.read(&buff_rcvd, maxLength: 1024)
let str = buff_rcvd.prefix(bytesRead).string
print("Read: \(str)")
// var buff_rcvd = Bytes(repeating: 0, count: 1024)
// let bytesRead = read(client_fd, &buff_rcvd, 1024)
// let str = buff_rcvd.prefix(bytesRead).string
// print("Read: \(str)")
// CFSocketCreate
// print(NSString(format:"Received: *%c*",buff_rcvd))
// writing one chat at a time
// var buff_send: CChar = 65 // character "A" defined as CChar
// write(client_fd, &buff_send, 1)
// print(NSString(format:"Sent: *%c*",buff_send))
print("")
}
}
public final class FoundationServerStream: ServerStream {
public let host: String
public let port: Int
public let securityLayer: SecurityLayer
public init(host: String, port: Int, securityLayer: SecurityLayer) throws {
self.host = host
self.port = port
self.securityLayer = securityLayer
}
public func accept() throws -> Stream {
fatalError()
}
}
public final class RawStream: Stream {
public let id: Int32
public var closed: Bool = false
public init(_ id: Int32) {
self.id = id
}
public func setTimeout(_ timeout: Double) throws {
// unsupported currently
}
public func close() throws {
closed = true
// TODO:
}
public func send(_ bytes: Bytes) throws {
guard !bytes.isEmpty else { return }
var buffer = bytes
let written = write(id, &buffer, buffer.count)
guard written == bytes.count else {
throw FoundationStream.Error.unableToCompleteWriteOperation
}
}
public func flush() throws {
// unsupported
}
public func receive(max: Int) throws -> Bytes {
var buffer = Bytes(repeating: 0, count: max)
let bytesRead = read(id, &buffer, max)
return buffer.prefix(bytesRead).array
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment