Good morning,

I am implementing a communication system in Haskell via UDP, and (I 
think) I've foud a bug in SocketPrim. Would you mind taking a look :-) ?

Consider the codes "udpSend.hs" and "udpRecv.hs":




-- udpSend.hs
-- send "Hello World" to port UDP:1500 of a remote host
--
-- compiled and tested with ghc-5.02.1
-- compile with: ghc -fglasgow-exts --make -package net -o udpSend 
udpSend.hs
-- run with: ./udpSend <remoteHost>

module Main where

import Word
import IO
import System
import SocketPrim
import BSD

receiverPort = 1500

main :: IO ()
main = do

  protoNum <- BSD.getProtocolNumber "udp"
  sock <- SocketPrim.socket AF_INET Datagram protoNum

  let sin_port = SocketPrim.aNY_PORT
      sin_addr = SocketPrim.iNADDR_ANY
      sockAddr = SocketPrim.SockAddrInet sin_port sin_addr in
    SocketPrim.bindSocket sock sockAddr

  args <- System.getArgs
  hEntry <- BSD.getHostByName (head args)

  -- SocketPrim doesn't export 'intToPortNumber'. Is there a better way 
to do this?
  let sin_port = Main.intToPortNumber receiverPort
      sin_addr = BSD.hostAddress hEntry
      sendAddr = SocketPrim.SockAddrInet sin_port sin_addr in
    SocketPrim.sendTo sock "Hello World" sendAddr

  return ()


intToPortNumber :: Int -> PortNumber
intToPortNumber v = PortNum (htons (fromIntegral v))

foreign import "htons" unsafe htons :: Word16 -> Word16




-- udpRecv.hs
-- listen port UDP:1500 and print received data
--
-- compiled and tested with ghc-5.02.1
-- compile with: ghc -fglasgow-exts --make -package net -o udpRecv 
udpRecv.hs
-- run with: ./udpRecv

module Main where

import Word
import IO
import System
import SocketPrim
import BSD

receiverPort = 1500
maxMsg = 100

main :: IO ()
main = do

  protoNum <- BSD.getProtocolNumber "udp"
  sock <- SocketPrim.socket AF_INET Datagram protoNum

  -- SocketPrim doesn't export 'intToPortNumber'. Is there a better way 
to do this?
  let sin_port = Main.intToPortNumber receiverPort
      sin_addr = SocketPrim.iNADDR_ANY
      sockAddr = SocketPrim.SockAddrInet sin_port sin_addr in
    SocketPrim.bindSocket sock sockAddr

  (recvHello, _, (SockAddrInet sin_port sin_addr)) <- 
SocketPrim.recvFrom sock maxMsg

  addr <- SocketPrim.inet_ntoa sin_addr
  IO.putStrLn ("udpRecv: from " ++ addr ++ ":UDP" ++ (show sin_port) ++ 
" : " ++ recvHello)

  return ()


intToPortNumber :: Int -> PortNumber
intToPortNumber v = PortNum (htons (fromIntegral v))

foreign import "htons" unsafe htons :: Word16 -> Word16




This is what happens in my machine (Debian GNU/Linux 2.2r3 with kernel 
2.2.19):

(terminal #1)
...$ ./udpRecv
(blocking at 'recvFrom')

(terminal #2)
...$ ./udpSend 10.0.10.195
...$

(terminal #1)

Fail: SocketPrim.hsc:241: Non-exhaustive patterns in case

...$


This happens because "family" enters the case statement with the value 0 
(zero) in SocketPrim.peekSockAddr.

If I build C versions of udpSend and udpReceive, I have:
  - udpSend.c  with  udpSend.c --> OK
  - udpSend.c  with  udpRecv.hs --> Fail
  - udpSend.hs  with  udpRecv.c --> OK

Therefore I think the problem is into the reception application (right?).


Thanks in advance.

Best regards,
Rafael Lorandi de Oliveira
Development Engineer - R&D
AsGa S/A
www.asga.com.br



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

Reply via email to