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()