Re: Network/Notwork?

2003-03-17 Thread C.Reinke

  - using hFlush does *not* seem to cure the problem??
 
 That's worrying, and it perhaps indicates that there's another problem
 somewhere.  I just tried a small test and hFlush does appear to do the
 right thing, so do you think you could boil down your example to
 something small that demonstrates the problem?  Does it happen only on
 Windows, or Un*x too?

Windows only, of course!-) On Solaris, I never even noticed there
might be a problem (it seems to work even without acknowledgment or
hFlush..).

I append my current test MyNetwork module - server and client are
the main functions of the respective apps, nothing else going on, so
it's very small, but for modified copies of some of the Network code
(for use on windows, you'll want to change to the other definition
of whatsWrong and uncomment c_getLastError).

On solaris (ghc version 5.04), this seems to work as shown. On win2k
(ghc version 5.04), with error reporting on, I get:

  $ ./server.exe 
  [1] 1388
  tcp: 6
  $ ./client.exe huhuadsfas
  tcp: 6
  CLIENT: huhuadsfas

  WSAGetLastError: 10054

  Fail: failed
  Action: hGetLine
  Handle: {loc=socket: 140,type=duplex
  (read-write),binary=True,buffering=line}
  Reason: No error
  File: socket: 140


  [1]+  Exit 1  ./server.exe

(on win98, not even the tcp number would be correct, hence the
hardcoded 6). The 10054 error from the hGetLine is the Connection
reset by peer.-message I mentioned earlier.

So it seems that on windows, when the client terminates, the
connection goes down and the server fails when trying to get the
message. Whereas on solaris, the message gets through anyway.

Uncommenting the hFlush in the client makes no difference
whatsoever.  Uncomment the acknowledgement in client and server
instead, and it works like a charm (although it does require an
asymmetry between the two processes - I have to know which one
lives longer..).

Over to you,
Claus

--
module MyNetwork where

import System(system,getArgs)
import IO(hPutStrLn
 ,hGetLine
 ,hClose
 ,hFlush
 ,hSetBuffering
 ,BufferMode(..)
 ,IOMode(..)
 ,Handle)
import Control.Exception as Exception
import Foreign
import Foreign.C
import Network hiding (listenOn,connectTo)
import Network.BSD(getProtocolNumber,getHostByName,hostAddress)
import Network.Socket(Family(..)
 ,SocketType(..)
 ,SockAddr(..)
 ,SocketOption(..)
 ,socket
 ,sClose
 ,setSocketOption
 ,bindSocket
 ,listen
 ,connect
 ,socketToHandle
 ,iNADDR_ANY
 ,maxListenQueue
 )

server :: IO ()
server = withSocketsDo $ do
  s - listenOn $ PortNumber 9000
  loop s
  where
loop s = do
  l - getInput s
  putStrLn $ SERVER: ++l
  loop s
getInput s = do
  (h,host,portnr) - accept s
  hSetBuffering h LineBuffering
  l - whatsWrong $ hGetLine h
  -- hPutStrLn h ack
  -- hClose h -- not a good idea?
  return l

client :: IO ()
client = withSocketsDo $ do
  args - getArgs
  h - connectTo localhost $ PortNumber 9000
  hSetBuffering h LineBuffering
  let l = unwords args
  putStrLn $ CLIENT: ++l
  hPutStrLn h l
  -- hFlush h
  -- hGetLine h  -- wait for acknowledgement
  return ()


{- only for winsock 
foreign import stdcall unsafe WSAGetLastError
  c_getLastError :: IO CInt
-}
{-
-- does this exist?
foreign import ccall unsafe getWSErrorDescr
  c_getWSError :: CInt - IO (Ptr CChar)
-}

whatsWrong act = act
{-
whatsWrong act = 
  Exception.catch act
  (\e- do
errCode - c_getLastError
--perr - c_getWSError errCode
--err - peekCString perr
putStrLn $ WSAGetLastError: ++show errCode
throw e)
-}

listenOn :: PortID  -- ^ Port Identifier
 - IO Socket   -- ^ Connected Socket

listenOn (PortNumber port) = do
proto - getProtocolNumber tcp
putStrLn $ tcp: ++show proto
let proto = 6 -- bug in ghc's getProtocolNumber..
bracketOnError
  (whatsWrong (socket AF_INET Stream proto))
  (sClose)
  (\sock - do
  setSocketOption sock ReuseAddr 1
  bindSocket sock (SockAddrInet port iNADDR_ANY)
  listen sock maxListenQueue
  return sock
  )

bracketOnError
  :: IO a   -- ^ computation to run first (\acquire resource\)
  - (a - IO b)  -- ^ computation to run last (\release resource\)
  - (a - IO c)-- ^ computation to run in-between
  - IO c   -- returns the value from the in-between computation
bracketOnError before after thing =
  block (do
a - before 
r - Exception.catch 
 (unblock (thing a))
 (\e - do { after a; throw e })
return r
 )

connectTo :: HostName   -- Hostname
- 

Re: Network/Notwork?

2003-03-17 Thread Peter Strand

Hi,

On Mon, Mar 17, 2003 at 07:01:20PM +, C.Reinke wrote:
 Windows only, of course!-) On Solaris, I never even noticed there
 might be a problem (it seems to work even without acknowledgment or
 hFlush..).

One explanation could be that hClose ends up calling close instead 
of closesocket under windows. 

I tried your example, and got the same error (under win2k).
But by using a slightly modified hClose, everything seemed to
work well.

In base/GHC/Handle.hs there is a preprocessor conditional on
mingw32_TARGET_OS which seems to be undefined in the distributed
compilation (I used 5.04.3). By explicitly calling closeFd there
instead of c_close it works for me.
Perhaps it should trigger on WITH_WINSOCK instead?


/Peter

___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Network/Notwork?

2003-03-17 Thread Sigbjorn Finne

The problem is that the necessary header file (config.h) isn't included
in that module. This was fixed a while ago in HEAD.

--sigbjorn

- Original Message - 
From: Peter Strand [EMAIL PROTECTED]
To: C.Reinke [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]
Sent: Monday, March 17, 2003 13:34
Subject: Re: Network/Notwork?


 
 Hi,
 
 On Mon, Mar 17, 2003 at 07:01:20PM +, C.Reinke wrote:
  Windows only, of course!-) On Solaris, I never even noticed there
  might be a problem (it seems to work even without acknowledgment or
  hFlush..).
 
 One explanation could be that hClose ends up calling close instead 
 of closesocket under windows. 
 
 I tried your example, and got the same error (under win2k).
 But by using a slightly modified hClose, everything seemed to
 work well.
 
 In base/GHC/Handle.hs there is a preprocessor conditional on
 mingw32_TARGET_OS which seems to be undefined in the distributed
 compilation (I used 5.04.3). By explicitly calling closeFd there
 instead of c_close it works for me.
 Perhaps it should trigger on WITH_WINSOCK instead?
 
___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Network/Notwork?

2003-03-12 Thread Claus Reinke
Happy with my Winsock work-arounds for my small client-/server-test,
I decided to try integrating the Network use into my target project, and
got nothing but trouble. Again, things that work happily under Unix
simply fail under windows. 

My best guess at the moment is that the socketToHandle conversion 
used within accept and connectTo simply doesn't work as advertised, 
under windows (at least, handle-based operations such as hGetLine
or hClose on the handles returned by accept/connectTo results in errors, 
whereas avoiding the socketToHandle conversion and using 
Network.Socket.send and Network.Socket.recv yields some improvements..).

A little more digging in mail-archives brings up the following rather
discouraging thread/message:

Socket library ghc 5.02.1
http://www.haskell.org/pipermail/glasgow-haskell-users/2001-November/002673.html

in which Sigbjorn summarizes: 

  FYI, in case you're planning on doing socket programming with GHC-5.02
  on a Win32 platform, stay away from using the higher-level Socket module,
  since its IO.Handle based view of sockets is just broken. Stick with the
  lower-level SocketPrim interface instead.

Is it just me doing something stupid, or is this problem still pertinent, for the
higher-level Network module in GHC-5.04? If the latter, could this please be 
flagged in the GHC documentation, so that people don't have to rediscover
the problem by painful debugging? (if the former, any suggestions on what 
I should try instead?)

Is anyone else here using GHC's Network module under Windows?

Claus

FPI: foreign problem interface


___
Glasgow-haskell-users mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users