[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