import asyncnet, asyncdispatch
var clients {.threadvar.}: seq[AsyncSocket]
proc processClient(client: AsyncSocket) {.async.} =
while true:
let line = await client.recvLine()
echo "Received: " & line & "!"
for c in clients:
await c.send(line & "\c\L")
proc serve() {.async.} =
clients = @[]
var server = newAsyncSocket()
server.bindAddr(Port(12345))
server.listen()
while true:
let client = await server.accept()
clients.add client
asyncCheck processClient(client)
asyncCheck serve()
runForever()
I can connect it with telnet or python, but as soon as a client disconnect I see printed a never-ending stream of empty lines Received: !
Is this expected? Am I doing something wrong?
Code, is fine but when socket is closed, the recv or recvLine will keep returning "" forever. So if you recv "" from the socket it means, that it has been closed and you should stop trying to recv from it.
Here is the fixed version:
import asyncnet, asyncdispatch
var clients {.threadvar.}: seq[AsyncSocket]
proc processClient(client: AsyncSocket) {.async.} =
while true:
let line = await client.recvLine()
if line != "":
echo "Received: " & line & "!"
for c in clients:
await c.send(line & "\c\L")
else:
#It seems sock received "", this it means connection has been closed.
client.close()#You should also close and remove the socket from the list
for i, c in clients:
if c == client:
clients.del(i)
break
echo("Client has left the server")
break
proc serve() {.async.} =
clients = @[]
var server = newAsyncSocket()
server.bindAddr(Port(12345))
server.listen()
while true:
let client = await server.accept()
clients.add client
asyncCheck processClient(client)
asyncCheck serve()
runForever()
import asyncnet, asyncdispatch
proc main() {.async.} =
var client = newAsyncSocket()
await client.connect("localhost", Port(12346))
await client.send("Hello\r\L")
let response = await client.recvLine()
echo "Received: " & response & "!"
waitFor main()
and it works fine. If I change this to
import asyncnet, asyncdispatch
proc main() {.async.} =
var client = newAsyncSocket()
await client.connect("localhost", Port(12346))
for s in ["Hi from the client", "This is Nim speaking"]:
echo "about to send " & s
await client.send(s & "\r\L")
let response = await client.recvLine()
echo "Received: " & response & "!"
waitFor main()
suddenly the client fails with SIGSEGV: Illegal storage access. (Attempt to read from nil?).
I guess the memory for the strings may be garbage collected, since it seems to work with an array of ints, but I am not sure. What is the interaction between async procs and garbage collection?