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

Reply via email to