I'm still learning the basics of Haskell and currently working through porting some Java code to Haskell. My current problem is in UDP recvFrom using Network.Socket.ByteString.
The problem is with this method:
public abstract SocketAddress receive(ByteBuffer dst) throws IOException
Receives a datagram via this channel.
If a datagram is immediately available, or if this channel
is in blocking mode and one eventually becomes available,
then the datagram is copied into the given byte buffer and
its source address is returned. If this channel is in
non-blocking mode and a datagram is not immediately available
then this method immediately returns null.
The thing is that when I use Network.Socket.ByteString.recvFrom my code blocks at this point waiting for the packet to come. It doesn't return something like Maybe to indicate if something was received or not (the same way in Java there is a null returned when no data was available)
I found this thread: https://mail.haskell.org/pipermail/haskell-cafe/2010-August/082725.html
At the end of it there are a couple of ways suggested: 1) FFI 2) run recvFrom in its own thread
I'm not sure I'm capable of using any of those approaches at this moment (not enough knowledge). What I want is to get something similar to Java way of non-blocking receive: get needed info if it is available or just nothing if there is no single UDP packet. Anyone can point out what would be a better approach, any code snippets, someone already handled this problem?
You could use socketToHandle
together with hGetNonBlocking
:
recvNonBlocking :: Socket -> Int -> IO ByteString
recvNonBlocking s n = do
hnd <- socketToHandle s ReadMode
hGetNonBlocking hnd n
However, keep in mind that you cannot use the Socket
after a call to socketToHandle
, so this is only feasible if you would close the Socket either way afterwards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With