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