Strange behavior with Network sockets
mrd
mdanish at andrew.cmu.edu
Fri Jan 19 18:16:31 EST 2007
This program listens on port 9000 and mirrors everything typed
into the client onto stdout, IF it is working correctly.
In GHC 6.6 (and HEAD), it seems to block unexpectedly, and this
strange behavior is related to hIsOpen and hIsEOF, somehow. It acts
like hIsOpen or hIsEOF is holding up the loop until input arrives, but
it still blocks at hGetLine.
The server ends up printing out lines that were typed into the client
a while ago, as if it were stuck on some kind of backlog but could
not catch up.
Not sure how to explain this without showing it, maybe this:
Client: Server:
------- -------
line1 handle isOpen = True; isEOF = False
line2 line1
line3 handle isOpen = True; isEOF = False
line4 line2
line5
line6
line7
Client has typed 7 lines and sent them to the server, but the server
has only printed out 2 lines.
If you remove the hIsOpen and hIsEOF calls, then the server will print
out all 7 lines immediately as they are submitted.
> import Control.Concurrent
> import Control.Concurrent.STM
> import System.IO
> import Network
> main = withSocketsDo $ do
> sock <- listenOn $ PortNumber 9000
> (h,_,_) <- accept sock
> ch <- atomically newTChan
> -- thread which pumps lines read
> -- from socket into channel
> forkIO . sequence_ . repeat $
> hGetLine h >>= atomically . writeTChan ch
> -- main thread just waits for data from channel
> -- and prints it to screen
> sequence_ . repeat $
> do isOpen <- hIsOpen h
> isEOF <- hIsEOF h
> putStrLn $ "handle isOpen = " ++ show isOpen
> ++ "; isEOF = " ++ show isEOF
> hFlush stdout
> line <- atomically $ readTChan ch
> putStrLn line
> hFlush stdout
Any idea what's going on?
--
-- Matthew Danish -- user: mrd domain: cmu.edu
-- OpenPGP public key: C24B6010 on keyring.debian.org
More information about the Glasgow-haskell-users
mailing list