Recently, I found a pure swift socket server and client called IBM BlueSocket.
It is suitable for me that it does server-cleint communication. It has a pretty simple sample.
but I encountered some problems.
1. How to run it on a GUI application's run loop and support multi connections?
sample code:
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
import Darwin
import Foundation
import Socket
#elseif os(Linux)
import Glibc
import Foundation
import Socket
#endif
class EchoServer {
static let QUIT: String = "QUIT"
let port: Int
var keepRunning: Bool = true
var listenSocket: Socket? = nil
init(port: Int) {
self.port = port
}
deinit {
self.listenSocket?.close()
}
func run() {
do {
try self.listenSocket = Socket.create()
guard let socket = self.listenSocket else {
print("Unable to unwrap socket...")
return
}
try socket.listen(on: self.port, maxBacklogSize: 10)
print("Listening on port: \(self.port)")
// Replace the listening socket with the newly accepted connection...
try socket.acceptConnection()
print("Accepted connection from: \(socket.remoteHostname) on port \(socket.remotePort)")
try socket.write(from: "Hello, type 'QUIT' to end session\n")
var bytesRead = 0
repeat {
let readData = NSMutableData()
bytesRead = try socket.read(into: readData)
if bytesRead > 0 {
guard let response = String(data: readData as Data, encoding: String.Encoding.utf8) else {
print("Error decoding response...")
readData.length = 0
break
}
// If the user typed `QUIT`, we'll shutdown the server...
if response.hasPrefix(EchoServer.QUIT) {
self.keepRunning = false
}
print("Server received from connection at \(socket.remoteHostname):\(socket.remotePort): \(response) ")
// Echo back to the client what we receivied...
let reply = "Server response: \n\(response)\n"
try socket.write(from: reply)
}
// No bytes read, the other side closed the connection...
if bytesRead == 0 {
break
}
} while self.keepRunning
socket.close()
} catch let error {
// See if it's a socket error or something else...
guard let socketError = error as? Socket.Error else {
print("Unexpected error...")
return
}
print("Error reported: \(socketError.description)")
}
}
}
let port = 1337
let server = EchoServer(port: port)
print("Connect using Terminal via 'telnet 127.0.0.1 \(port)'")
server.run()