
I'm trying to write a simple program that involves UDP. I was hoping something like this would work: module Main where import Network.Socket main = withSocketsDo main2 main2 = do s <- socket AF_INET Datagram defaultProtocol putStrLn "Waiting..." x <- recv s 100 putStrLn x Unfortunately, that doesn't work at all. It immediately throws an exception ("unknown error"). But then, the whole module seems to be completely undocumented. I managed to find a tiny amount of info online about the underlying C API, but I still don't get how the Haskell interface is supposed to be used. Any hints?

Andrew Coppin wrote:
I'm trying to write a simple program that involves UDP. I was hoping something like this would work:
[...]
How about using bindSocket? At least that's the main difference between your code snippet and our (UDP-using) barracuda project :)
main2 = do s <- socket AF_INET Datagram defaultProtocol
bindSocket s ...
putStrLn "Waiting..." x <- recv s 100 putStrLn x
[...]
//Stephan -- Früher hieß es ja: Ich denke, also bin ich. Heute weiß man: Es geht auch so. - Dieter Nuhr

The network library is no more than an FFI library to a Berkeley
socket interface and as such it implicitly expects you to know sockets
already (eg. from programming in C). One advantage here is reading
man pages actually helps (unlike with most Haskell coding) and you can
also make equivalent C programs to test things out.
In the long term we should design and build a more functional network library.
Thomas
On Sat, Jan 31, 2009 at 9:19 PM, Stephan Friedrichs
Andrew Coppin wrote:
I'm trying to write a simple program that involves UDP. I was hoping something like this would work:
[...]
How about using bindSocket? At least that's the main difference between your code snippet and our (UDP-using) barracuda project :)
main2 = do s <- socket AF_INET Datagram defaultProtocol
bindSocket s ...
putStrLn "Waiting..." x <- recv s 100 putStrLn x
[...]
//Stephan
--
Früher hieß es ja: Ich denke, also bin ich. Heute weiß man: Es geht auch so.
- Dieter Nuhr _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Thomas DuBuisson wrote:
The network library is no more than an FFI library to a Berkeley socket interface and as such it implicitly expects you to know sockets already (eg. from programming in C). One advantage here is reading man pages actually helps (unlike with most Haskell coding) and you can also make equivalent C programs to test things out.
Yes, that's kind of the problem; I don't know how to do this at the C level, and I can't seem to Google it. :-} Ah well, I'll ask around. Somebody must know. ;-)
In the long term we should design and build a more functional network library.
Well, I guess having a library that gives you low-level access means that anybody who wants to have a go can easily build something nicer on top of that. (As opposed to, say, file I/O where there is only the high-level interface, so if you want to do something that isn't implemented... you can't.)

On Sat, Jan 31, 2009 at 9:36 PM, Andrew Coppin
Thomas DuBuisson wrote:
The network library is no more than an FFI library to a Berkeley socket interface and as such it implicitly expects you to know sockets already (eg. from programming in C). One advantage here is reading man pages actually helps (unlike with most Haskell coding) and you can also make equivalent C programs to test things out.
Yes, that's kind of the problem; I don't know how to do this at the C level, and I can't seem to Google it. :-}
Ah well, I'll ask around. Somebody must know. ;-)
Ahh, then see Beej's guide [1] if you wish to learn at the C level. On another note: when making your Haskell app if you are at all performance concerned then you should use network-bytestring [2]. [1] http://beej.us/guide/bgnet/ [2] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/network-bytestrin...

Try something like this:
module Main where
import Network.Socket
main = withSocketsDo $ do
-- Make a UDP socket
s <- socket AF_INET Datagram defaultProtocol
-- We want to listen on all interfaces (0.0.0.0)
bindAddr <- inet_addr "0.0.0.0"
-- Bind to 0.0.0.0:30000
bindSocket s (SockAddrInet 30000 bindAddr)
-- Read a message of max length 1000 from some one
(msg,len,from) <- recvFrom s 1000
putStrLn $ "Got the following message from " ++ (show from)
putStrLn msg
Does this help? As Stephan said, you missed the bind step.
/jve
On Sun, Jan 25, 2009 at 11:22 AM, Andrew Coppin wrote: I'm trying to write a simple program that involves UDP. I was hoping
something like this would work: module Main where import Network.Socket main = withSocketsDo main2 main2 = do
s <- socket AF_INET Datagram defaultProtocol
putStrLn "Waiting..."
x <- recv s 100
putStrLn x Unfortunately, that doesn't work at all. It immediately throws an exception
("unknown error"). But then, the whole module seems to be completely
undocumented. I managed to find a tiny amount of info online about the
underlying C API, but I still don't get how the Haskell interface is
supposed to be used. Any hints? _______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

John Van Enk wrote:
Try something like this:
module Main where
import Network.Socket
main = withSocketsDo $ do -- Make a UDP socket s <- socket AF_INET Datagram defaultProtocol
-- We want to listen on all interfaces (0.0.0.0) bindAddr <- inet_addr "0.0.0.0"
-- Bind to 0.0.0.0:30000 http://0.0.0.0:30000 bindSocket s (SockAddrInet 30000 bindAddr)
-- Read a message of max length 1000 from some one (msg,len,from) <- recvFrom s 1000
putStrLn $ "Got the following message from " ++ (show from) putStrLn msg
Does this help? As Stephan said, you missed the bind step.
That works great, thanks. Yeah, I just assumed that the bind step was only necessary for connection-oriented protocols. (Interestingly enough, the matching "send" program doesn't bind at all, yet seems to work fine...)

2009/2/1 Andrew Coppin
Yeah, I just assumed that the bind step was only necessary for connection-oriented protocols. (Interestingly enough, the matching "send" program doesn't bind at all, yet seems to work fine...)
socket() system call creates a socket (a descriptor) that you can identify. bind() creates an identity for the socket so that applications outside can refer to it (using ip:port); it also enables the kernel to pass the received data to your application. sendto() doesn't require that identity. -- Vimal

Andrew Coppin ha scritto:
[...]
Yeah, I just assumed that the bind step was only necessary for connection-oriented protocols. (Interestingly enough, the matching "send" program doesn't bind at all, yet seems to work fine...)
For a client (that is, when you call connect), the kernel chooses the source IP address once the socket is connected. Of course, for a server this is not feasible, since the address *must* be know to external programs, if they want to connect to the server. For more details, I really suggest to read a good book like "UNIX Network Programming", by W. Richard Stevens. Regards Manlio Perillo
participants (6)
-
Andrew Coppin
-
John Van Enk
-
Manlio Perillo
-
Stephan Friedrichs
-
Thomas DuBuisson
-
Vimal