2013-05-21 20 views
5

Come posso ottenere che Haskell ascolti UDP e TCP sulla stessa porta?Ascolta su TCP e UDP sulla stessa porta

Ecco il codice che ho finora (sulla base di acme-http):

listenOn portm = do                
    protoTCP <- getProtocolNumber "tcp"           
    E.bracketOnError                
    (socket AF_INET Stream protoTCP)           
    sClose                 
    (\sock -> do                
     setSocketOption sock ReuseAddr 1          
     setSocketOption sock NoDelay 1          
     bindSocket sock (SockAddrInet (fromIntegral portm) iNADDR_ANY)   
     listen sock (max 1024 maxListenQueue)        
     return sock               
    )                  
    protoUDP <- getProtocolNumber "udp"           
    E.bracketOnError                
    (socket AF_INET Datagram protoUDP)          
    sClose                 
    (\sock -> do                
     setSocketOption sock ReuseAddr 1          
     bindSocket sock (SockAddrInet (fromIntegral portm) iNADDR_ANY)   
     return sock               
    )                  

ho compila bene, ma ottengo l'errore follow runtime:

user error (accept: can't perform accept on socket ((AF_INET,Datagram,17)) in status Bound) 

Purtroppo, documentazione su la programmazione di rete in Haskell è un po 'limitata (come al solito). Non so davvero dove dovrei cercare di capire queste cose.

[UPDATE]
Per qualcuno è interessato, ecco il risultato:

https://github.com/joehillen/acme-sip/blob/master/Acme/Serve.hs

mi rendo conto che c'è un sacco di spazio per migliorare, ma funziona.

+3

I dettagli della configurazione potrebbero essere utili. Il tuo codice funziona perfettamente con GHC 7.6.3 x86-64, Linux, usando la rete 2.4.1.2. Inoltre, il jab sulla documentazione non è necessario - La rete è moderatamente ben documentata, è principalmente chiamata C diretta, quindi le pagine man sono utili e il pacchetto è su github, così puoi sentirti libero di inviare patch. –

risposta

14

Non sembra che ci sia qualcosa di sbagliato in questo codice, ma da qualche altra parte il tuo codice sembra chiamare accept() sul socket UDP, che non è legale. Tutto ciò che devi fare con un socket UDP è ricevere da esso e inviare con esso.