Last active
February 7, 2025 23:54
-
-
Save algebraic-dev/ce45fc2a9d18cb74582e3446c28153ab to your computer and use it in GitHub Desktop.
Probably a problem of TCP/IP Buffer freeze
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Std.Internal.Async | |
import Std.Internal.UV | |
import Std.Net.Addr | |
open Std.Internal.IO.Async.TCP.Socket | |
open Std.Internal.IO.Async.TCP | |
open Std.Internal.IO.Async | |
open Std.Net | |
-- The monad to make the code simpler to read. | |
structure Async (α : Type) where | |
run : IO (AsyncTask α) | |
instance : Monad Async where | |
pure x := Async.mk (pure (AsyncTask.pure x)) | |
bind ma f := Async.mk do | |
let task ← ma.run | |
task.bindIO fun a => (f a).run | |
def await (task : IO (AsyncTask α)) : Async α := | |
Async.mk task | |
def parallel (task : Async α) : IO Unit := | |
discard task.run | |
def block (task : Async α) : IO α := | |
task.run >>= AsyncTask.block | |
instance : MonadLift IO Async where | |
monadLift io := Async.mk (io >>= (pure ∘ AsyncTask.pure)) | |
-- Client | |
partial def writeLoop (client : Socket.Client) (message : String) : Async Unit := do | |
await <| client.send (String.toUTF8 message) | |
writeLoop client message | |
def echoClient (addr : SocketAddress) (message : String) : Async Unit := do | |
let socket ← Client.mk | |
await <| socket.connect addr | |
writeLoop socket message | |
-- Server | |
partial def echoLoop (client : Socket.Client) : Async Unit := do | |
let message ← await <| client.recv 1024 | |
IO.println s!"received: {String.fromUTF8! message}" | |
await <| client.send message | |
echoLoop client | |
partial def acceptLoop (server : Socket.Server) : Async Unit := do | |
let client ← await server.accept | |
parallel (echoLoop client) | |
acceptLoop server | |
def echoServer (addr : SocketAddress) : Async Unit := do | |
let socket ← Server.mk | |
socket.bind addr | |
socket.listen 128 | |
acceptLoop socket | |
-- Running | |
def main : IO Unit := do | |
let addr := SocketAddressV4.mk (.ofParts 127 0 0 1) 8080 | |
parallel (echoServer addr) | |
block (echoClient addr "monad") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment