Send Beginners mailing list submissions to
[email protected]
To subscribe or unsubscribe via the World Wide Web, visit
http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Network client - reading and writing to a socket (Manfred Lotz)
2. Re: Network client - reading and writing to a socket
(David Place)
3. Re: Network client - reading and writing to a socket
(Manfred Lotz)
4. Re: Network client - reading and writing to a socket
(David Place)
5. Re: Network client - reading and writing to a socket
(Manfred Lotz)
6. Re: Network client - reading and writing to a socket
(David Place)
7. Re: Network client - reading and writing to a socket
(Manfred Lotz)
8. Re: Network client - reading and writing to a socket
(David Place)
9. Re: Network client - reading and writing to a socket
(Manfred Lotz)
10. Re: Network client - reading and writing to a socket
(Patrick LeBoutillier)
11. Re: Haskell-style types in C or C++ (Ertugrul Soeylemez)
----------------------------------------------------------------------
Message: 1
Date: Sun, 31 Jul 2011 17:39:48 +0200
From: Manfred Lotz <[email protected]>
Subject: [Haskell-beginners] Network client - reading and writing to a
socket
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII
Hi there,
I'm trying to write a network client which connects to an IMAP server
thus reading from and writing to socket 143.
I have an initial solution which works except that laziness bites me.
Perhaps the whole solution using connectTo and handle is the wrong
approach.
Here is the code:
module Main where
import System.IO
import qualified Data.ByteString.Char8 as B
import Network
server :: String
server = "127.0.0.1"
port :: PortID
port = PortNumber 143
sendMsg :: Handle -> String -> IO ()
sendMsg h m = do
putStrLn ("Sending command: " ++ m)
B.hPutStrLn h (B.pack m) >> hFlush h
recvMsg :: Handle -> IO B.ByteString
recvMsg h = do
c <- B.hGet h 1
c' <- B.hGetNonBlocking h 40000
return $ B.concat [c,c']
main :: IO ()
main = withSocketsDo $ do
h <- connectTo server port
hSetBuffering h LineBuffering
imapDialog h
imapDialog :: Handle -> IO ()
imapDialog h = do
greet <- recvMsg h
B.putStrLn greet
sendMsg h "1 LOGIN manfred \"password\""
resp <- recvMsg h
B.putStrLn resp
sendMsg h "2 SELECT HAM-learn"
resp1 <- recvMsg h
B.putStrLn resp1
sendMsg h "3 FETCH 1:* (uid flags internaldate body[header.fields
(Message-Id)])"
resp2 <- recvMsg h
B.putStrLn resp2
sendMsg h "4 FETCH 1 (rfc822)"
resp3 <- recvMsg h
B.putStrLn resp3
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?
--
Manfred
------------------------------
Message: 2
Date: Sun, 31 Jul 2011 12:02:16 -0400
From: David Place <[email protected]>
Subject: Re: [Haskell-beginners] Network client - reading and writing
to a socket
To: Manfred Lotz <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
On Jul 31, 2011, at 11:39 AM, Manfred Lotz wrote:
> How could I force to get the whole message?
Did you try hFlush?
------------------------------
Message: 3
Date: Sun, 31 Jul 2011 18:17:25 +0200
From: Manfred Lotz <[email protected]>
Subject: Re: [Haskell-beginners] Network client - reading and writing
to a socket
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII
On Sun, 31 Jul 2011 12:02:16 -0400
David Place <[email protected]> wrote:
>
> On Jul 31, 2011, at 11:39 AM, Manfred Lotz wrote:
>
> > How could I force to get the whole message?
>
> Did you try hFlush?
>
>
I tried it like this
recvMsg :: Handle -> IO B.ByteString
recvMsg h = do
c <- B.hGet h 1
hFlush h
c' <- B.hGetNonBlocking h 40000
return $ B.concat [c,c']
and it didn't help. Still an incomplete message.
--
Manfred
------------------------------
Message: 4
Date: Sun, 31 Jul 2011 12:20:17 -0400
From: David Place <[email protected]>
Subject: Re: [Haskell-beginners] Network client - reading and writing
to a socket
To: Manfred Lotz <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
____________________
David Place
Owner, Panpipes Ho! LLC
http://panpipesho.com
[email protected]
On Jul 31, 2011, at 12:17 PM, Manfred Lotz wrote:
> c <- B.hGet h 1
> hFlush h
> c' <- B.hGetNonBlocking h 40000
Try putting one here too. Can't hurt right?
> return $ B.concat [c,c']
------------------------------
Message: 5
Date: Sun, 31 Jul 2011 18:25:04 +0200
From: Manfred Lotz <[email protected]>
Subject: Re: [Haskell-beginners] Network client - reading and writing
to a socket
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII
On Sun, 31 Jul 2011 12:20:17 -0400
David Place <[email protected]> wrote:
>
> ____________________
> David Place
> Owner, Panpipes Ho! LLC
> http://panpipesho.com
> [email protected]
>
>
>
> On Jul 31, 2011, at 12:17 PM, Manfred Lotz wrote:
>
> > c <- B.hGet h 1
> > hFlush h
> > c' <- B.hGetNonBlocking h 40000
>
> Try putting one here too. Can't hurt right?
>
> > return $ B.concat [c,c']
>
Now I have
recvMsg h = do
c <- B.hGet h 1
hFlush h
c' <- B.hGetNonBlocking h 40000
hFlush h
return $ B.concat [c,c']
Doesn't help either.
--
Manfred
------------------------------
Message: 6
Date: Sun, 31 Jul 2011 12:42:45 -0400
From: David Place <[email protected]>
Subject: Re: [Haskell-beginners] Network client - reading and writing
to a socket
To: Manfred Lotz <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
Shouldn't be laziness that is biting you. You are using strict ByteStrings.
I'm stumped! Did you try artificially inserting something like this to force c
and c'?
On Jul 31, 2011, at 12:25 PM, Manfred Lotz wrote:
> recvMsg h = do
> c <- B.hGet h 1
> hFlush h
print c
> c' <- B.hGetNonBlocking h 40000
print c'
> hFlush h
> return $ B.concat [c,c']
------------------------------
Message: 7
Date: Sun, 31 Jul 2011 19:20:06 +0200
From: Manfred Lotz <[email protected]>
Subject: Re: [Haskell-beginners] Network client - reading and writing
to a socket
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII
On Sun, 31 Jul 2011 12:42:45 -0400
David Place <[email protected]> wrote:
> Shouldn't be laziness that is biting you. You are using strict
> ByteStrings. I'm stumped! Did you try artificially inserting
> something like this to force c and c'?
>
> On Jul 31, 2011, at 12:25 PM, Manfred Lotz wrote:
>
> > recvMsg h = do
> > c <- B.hGet h 1
> > hFlush h
>
> print c
>
> > c' <- B.hGetNonBlocking h 40000
>
> print c'
>
> > hFlush h
> > return $ B.concat [c,c']
>
>
Didn't help either.
If I add another
resp4 <- recvMsg h
B.putStrLn resp4
at the end of imapDialog then I get the rest of the message.
--
Manfred
------------------------------
Message: 8
Date: Sun, 31 Jul 2011 13:46:56 -0400
From: David Place <[email protected]>
Subject: Re: [Haskell-beginners] Network client - reading and writing
to a socket
To: Manfred Lotz <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
On Jul 31, 2011, at 1:20 PM, Manfred Lotz wrote:
> Didn't help either.
>
>
> If I add another
>
> resp4 <- recvMsg h
> B.putStrLn resp4
>
> at the end of imapDialog then I get the rest of the message.
Sorry, I'm just shooting in the dark here. Did you try this?
hSetBuffering h NoBuffering
------------------------------
Message: 9
Date: Sun, 31 Jul 2011 19:57:00 +0200
From: Manfred Lotz <[email protected]>
Subject: Re: [Haskell-beginners] Network client - reading and writing
to a socket
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII
On Sun, 31 Jul 2011 13:46:56 -0400
David Place <[email protected]> wrote:
> On Jul 31, 2011, at 1:20 PM, Manfred Lotz wrote:
>
> > Didn't help either.
> >
> >
> > If I add another
> >
> > resp4 <- recvMsg h
> > B.putStrLn resp4
> >
> > at the end of imapDialog then I get the rest of the message.
>
> Sorry, I'm just shooting in the dark here. Did you try this?
>
No sorry. I'm happy you try to help me.
> hSetBuffering h NoBuffering
>
Didn't make a difference.
--
Manfred
------------------------------
Message: 10
Date: Sun, 31 Jul 2011 15:14:23 -0400
From: Patrick LeBoutillier <[email protected]>
Subject: Re: [Haskell-beginners] Network client - reading and writing
to a socket
To: Manfred Lotz <[email protected]>
Cc: [email protected]
Message-ID:
<CAJcQsbhRmhCRA=jioiyx9ouw+u_1ebz8tt0krfo7pnl1fs1...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
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
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
--
=====================
Patrick LeBoutillier
Rosem?re, Qu?bec, Canada
------------------------------
Message: 11
Date: Sun, 31 Jul 2011 21:58:06 +0200
From: Ertugrul Soeylemez <[email protected]>
Subject: Re: [Haskell-beginners] Haskell-style types in C or C++
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII
Christopher Howard <[email protected]> wrote:
> One of the things that I love about Haskell is the syntax for creating
> user defined types. E.g.:
>
> Data QueryResult = NoResult | DatabaseError String | Results [String]
>
> I can prototype an entire program around these self-made types and it
> is a lot of fun. Out of intellect curiosity, though: what would be the
> equivalent construction in C or C++? (Say, for the type defined
> above).
I think, the closest and cleanest translation is a set of four classes,
one QueryResult superclass with subclasses NoResult, DatabaseError and
Results. This also gives you something resembling Haskell's value
constructors, although not for free. Finally it helps with separation
of concerns, when you write accessor functions. You don't get pattern
matching, but you can get combinators like 'maybe' for Maybe or 'either'
for Either.
Unions work, too, but they are not nearly as clean. In general, avoid
unions in C++, even though they seem to be a natural way to express
ADTs. They really are not. Class hierarchies are the way to go.
Greets,
Ertugrul
--
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://ertes.de/
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 37, Issue 70
*****************************************