[Haskell-beginners] Network client - reading and writing to a socket

David McBride dmcbride at neondsl.com
Mon Aug 1 00:22:19 CEST 2011


Sorry I said network-attoparsec, the attoparsec library is all you
need.  I'm not sure where I got network-attoparsec from.

On Sun, Jul 31, 2011 at 6:21 PM, David McBride <dmcbride at neondsl.com> wrote:
> It seems you are expected to fetch until you have the entire thing.
> You can't just fetch 40000 and hope you get it all.  If you do it
> blocking, it will be almost guaranteed to block unless there were
> 40000 to fetch.  If you do it non blocking, you have to keep fetching
> until you are sure you have the entire message.
>
> If you are doing this as simply as possible, that means you have to
> fetch, and then repeatedly check the string until you are sure you
> have the whole thing.  You'll do that by fetching once, checking the
> beginning of the string for the {342} in the following example from
> the rfc:
>
> C:    a004 fetch 12 body[header]
> S:    * 12 FETCH (BODY[HEADER] {342}
> S:    Date: Wed, 17 Jul 1996 02:23:25 -0700 (PDT)
> S:    From: Terry Gray <gray at cac.washington.edu>
> S:    Subject: IMAP4rev1 WG mtg summary and minutes
> S:    To: imap at cac.washington.edu
> S:    cc: minutes at CNRI.Reston.VA.US, John Klensin <KLENSIN at MIT.EDU>
> S:    Message-Id: <B27397-0100000 at cac.washington.edu>
> S:    MIME-Version: 1.0
> S:    Content-Type: TEXT/PLAIN; CHARSET=US-ASCII
> S:
> S:    )
>
> And then fetching until you have the next 342 characters.  This is
> pretty tedious in any language, not just haskell, but that's how this
> protocol is.
>
> If you want to do this the haskell way, which I highly recommend, I
> would pull out the network-attoparsec library.  You should be able to
> use parseWith and pass it a recv function that returns bytestrings.
> Write a simple parser which will look for "* <num> FETCH
> ([a-zA-Z]+\[[a-zA-Z]+\] {[0-9]+} and then use that last number to take
> (take is an attoparsec function) that last byte count.  If you wire
> this up to your network socket, it will parse and slurp up the
> response and it will pull the exact number of bytes needed and your
> code will be very elegant.  Attoparsec is a little hard to use at
> first, but it is well worth if if you have a mind to parse internet
> protocols.
>
> On Sun, Jul 31, 2011 at 3:14 PM, Patrick LeBoutillier
> <patrick.leboutillier at gmail.com> wrote:
>> Manfred,
>>
>>> The problem is that the message itself is some 30K big and I only
>>> get some 16K of the message.
>>>
>>> How could I force to get the whole message?
>>
>> My guess is that you can't. This call:
>>
>> c' <- B.hGetNonBlocking h 40000
>>
>> tries to read as much as it can (up to 40000 bytes) but it won't block
>> to wait for data. Perhaps the rest of your message is in a different
>> TCP packet or delayed or whatever, but I think you have to keep on
>> reading (and maybe block) until you know you have read the entire
>> message. The IMAP specs will tell you how to identify the "end of the
>> message".
>>
>> BTW: This issue is not Haskell specific. If you implement the same
>> code in C, Perl or Java you will have to deal with the same problem.
>> When you read from a socket, there is no general way of knowing that
>> the other side has sent everything.
>>
>>
>> Patrick
>>
>>>
>>> --
>>> Manfred
>>>
>>>
>>>
>>> _______________________________________________
>>> Beginners mailing list
>>> Beginners at haskell.org
>>> http://www.haskell.org/mailman/listinfo/beginners
>>>
>>
>>
>>
>> --
>> =====================
>> Patrick LeBoutillier
>> Rosemère, Québec, Canada
>>
>> _______________________________________________
>> Beginners mailing list
>> Beginners at haskell.org
>> http://www.haskell.org/mailman/listinfo/beginners
>>
>



More information about the Beginners mailing list