From 9aa7d66331b70a38a1235fdd93bcab250f3f2d5a Mon Sep 17 00:00:00 2001 From: Christian Ulrich Date: Fri, 8 May 2020 19:34:37 +0200 Subject: [PATCH] initial commit --- asyncreadline.nim | 18 +++++++++++ syni_prototype.nim | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 asyncreadline.nim create mode 100644 syni_prototype.nim diff --git a/asyncreadline.nim b/asyncreadline.nim new file mode 100644 index 0000000..7990262 --- /dev/null +++ b/asyncreadline.nim @@ -0,0 +1,18 @@ +## asyncReadline as discussed at https://github.com/nim-lang/Nim/issues/11564 + +import asyncdispatch, threadpool + +proc asyncReadline*(): Future[string] = + let event = newAsyncEvent() + let future = newFuture[string]("asyncReadline") + proc readlineBackground(event: AsyncEvent): string = + result = stdin.readline() + event.trigger() + let flowVar = spawn readlineBackground(event) + proc callback(fd: AsyncFD): bool = + future.complete(^flowVar) + true + addEvent(event, callback) + return future + + diff --git a/syni_prototype.nim b/syni_prototype.nim new file mode 100644 index 0000000..d5280a9 --- /dev/null +++ b/syni_prototype.nim @@ -0,0 +1,77 @@ +import + asyncnet, + asyncdispatch, + asyncreadline + +from strutils import format +from nativesockets import setSockOptInt +from os import paramCount, paramStr + +var IPPROTO_IP {.importc: "IPPROTO_IP", header: "".}: cint +var IP_TTL {.importc: "IP_TTL", header: "".}: cint + +proc usage() = + echo("Usage: $# client|server".format(paramStr(0))) + +#proc punchHoleAsClient(socket: AsyncSocket) {.async.} = +# + +proc processInput(client: AsyncSocket) {.async.} = + while true: + let input = await asyncReadline() + await client.send(input & "\c\L") + +proc runClient() {.async.} = + var client = newAsyncSocket() + client.setSockOpt(OptReuseAddr, true) + client.getFd().setSockOptInt(IPPROTO_IP, IP_TTL, 2) + client.bindAddr(Port(1234)) + try: + await client.connect("127.0.0.1", Port(4321)) + let (address, port) = client.getPeerAddr() + echo("connected to $#:$#!".format(address, port.uint16)) + asyncCheck processInput(client) + while true: + let line = await client.recvLine() + if line.len == 0: break + echo("server responded: $#".format(line)) + except OSError as e: + echo("Error: $#".format(e.msg)) + +proc processClient(client: AsyncSocket) {.async.} = + while true: + let line = await client.recvLine() + if line.len == 0: break + echo("client sent message: $#".format(line)) + await client.send(line & "\c\L") + +proc runServer() {.async.} = + var server = newAsyncSocket() + server.setSockOpt(OptReuseAddr, true) + server.bindAddr(Port(4321)) + server.listen() + echo("listening on port 4321") + while true: + let client = await server.accept() + let (address, port) = client.getPeerAddr() + echo("client $#:$# connected!".format(address, port.uint16())) + asyncCheck processClient(client) + +proc main() = + if paramCount() != 1: + usage() + return + case paramStr(1) + of "client": + asyncCheck runClient() + of "server": + asyncCheck runServer() + else: + usage() + try: + runForever() + except ValueError: + discard + +when isMainModule: + main()