78 lines
2.0 KiB
Nim
78 lines
2.0 KiB
Nim
|
import
|
||
|
asyncnet,
|
||
|
asyncdispatch,
|
||
|
asyncreadline
|
||
|
|
||
|
from strutils import format
|
||
|
from nativesockets import setSockOptInt
|
||
|
from os import paramCount, paramStr
|
||
|
|
||
|
var IPPROTO_IP {.importc: "IPPROTO_IP", header: "<netinet/in.h>".}: cint
|
||
|
var IP_TTL {.importc: "IP_TTL", header: "<netinet/in.h>".}: 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()
|