Hi Nate, just reversed client/server with loggedin and download without
addional socket... sorry the structure is just better
based on @Stefan_Salewski work...
# reverseserver.nim
# see also https://nim-lang.org/docs/asyncnet.html#examples-chat-server
import asyncdispatch,asyncfile,asyncnet,os,strutils,base64,threadpool
const
port = Port(12345)
proc ask(prompt:string): string=
stdout.write(prompt)
let bla = stdin.readLine()
return bla
proc asyncWaitFor[T] (work: FlowVar[T], sleepTime: int = 100):Future[T]
{.async.} =
## waits asynchron for a FlowVar to finish
while not work.isReady :
await sleepAsync(sleepTime)
return ^work
proc processCommand(command: string, socket: AsyncSocket){.async.}=
waitFor socket.send(command & "\c\l")
# Receive the number of lines from the client
let line = await socket.recvLine()
echo "Received Message: ", line
var numLines = line.parseInt
echo "Receiving ", numLines, " lines"
# then recv only the amount of lines requested
for _ in 0 .. numLines-1:
let line = await socket.recvLine()
if not command.startsWith("download"):
echo ">> ", line
else:
echo line
let decoded = decode(line)
let work = spawn ask("filename to save?>")
let input = waitFor asyncWaitFor(work)
var file = openAsync(input, fmWrite)
await file.write(decoded)
proc serve() {.async.} =
var server = newAsyncSocket()
server.setSockOpt(OptReuseAddr, true)
server.bindAddr(port)
server.listen()
stdout.writeLine("The Server is now listening for incoming connections
... ")
while true:
let client = await server.accept()
while true:
let work = spawn ask(">")
let input = waitFor asyncWaitFor(work)
waitFor processCommand(input,client)
asyncCheck serve()
runForever()
Run
# reverseclient.nim
import threadpool, asyncdispatch, asyncnet, strutils, base64,asyncfile,os
const
port = Port(12345)
ip = "localhost"
proc doConnect(socket: AsyncSocket, serverAddr: string) {.async.} =
echo("Connecting to ", serverAddr)
await socket.connect(serverAddr, port)
echo("Connected!")
proc processClient(client: AsyncSocket):Future[bool] {.async.} =
while true:
let input = await client.recvLine()
if input.len == 0: return false
if input == "loggedin":
let username = getEnv("USERNAME")
let message = "Logged in user:"
# send length of 1 for one line
await client.send("1\c\L")
await client.send(message & username & "\c\L")
elif input.startsWith("download"):
let cmd = input.split(" ")
if cmd.len == 2:
var my_path = cmd[1]
try:
var file = openAsync(my_path, fmRead)
var bytes = await file.readAll()
let encoded = encode(bytes)
await client.send("1\c\L")
await client.send(encoded & "\c\L")
except:
await client.send("0\c\L")
else:
await client.send("0\c\L")
else:
await client.send("1\c\L")
await client.send("unknown command" & "\c\L")
return true
proc main()=
echo("Chat application started")
var socket = newAsyncSocket()
waitFor doConnect(socket, ip)
stdout.writeLine("The connection has been established.")
var check = true
while check:
check = waitFor processClient(socket)
main()
Run