[Haskell-cafe] Simple network client
Jules Bean
jules at jellybean.co.uk
Wed Jan 30 07:32:42 EST 2008
Timo B. Hübel wrote:
> On Wednesday 30 January 2008 13:03:27 you wrote:
>> Just don't use hGetContents in any serious code, or any program longer
>> than 4 lines.
>
> What else do you suggest? I just want to read something out of the socket
> without knowing it's length beforehand (my example here used ordinary
> Strings, but actually I want to do it with ByteStrings).
How much shall you read?
Will you wait if not that much data is available?
This is a question all network protocols have to answer!
There are two traditional solutions:
Implement a line based protocol. Read one line at a time. In that case
hGetLine is your friend. (Actually any delimeter, but it's traditionally
lines)
Implement a known-chunk-size protocol, either fixed to a constant N, or
transmit a length word as the first word. In that case, the
extraordinarly ugly and clumsy hGetBuf is your friend, but you might
wrap it into something more comfortable.
The third, but more sophisticated answer is to use non-blocking IO, read
'only what is available', decide if it's enough to process, if not
store it in some local buffer until next time. This is much more work
and easy to implement bugs in, but you need it for true streaming
protocols. In that case hGetBufNonBlocking is your friend.
The vast majority of internet protocols are line based, at some level,
and so use solution 1.
In cases 2 and 3 it happens that ByteString offers a cleaner API than
System.IO, even if you didn't really want to use ByteString, since it
provides hGet and hGetNonBlocking, no messing around with Ptrs.
I strongly suspect for your example you want solution 1 and hGetLine,
though. (Which works just as well with or without ByteString)
Jules
PS "whatever you do, just don't use hGetContents" , print this out onto
a T-shirt transfer and apply it to the front of your monitor.
More information about the Haskell-Cafe
mailing list