Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Listen on TCP and UDP on the same port

How can I get Haskell to listen for UDP and TCP on the same port?

Here is the code I have so far (based on 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                                                         
    )                                                                       

I compiles fine, but I get the follow runtime error:

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

Unfortunately, documentation on network programming in Haskell is a bit limited (as usual). I don't really know where I'm supposed to look to figure this stuff out.

[UPDATE]
For anyone is interested, here is the result:

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

I realize there is a lot of room for improvement, but it works.

like image 984
Joe Hillenbrand Avatar asked May 21 '13 05:05

Joe Hillenbrand


People also ask

Can two processes listen on same port?

No. Only one application can bind to a port at a time, and behavior if the bind is forced is indeterminate.

Are UDP and TCP ports separate?

The UDP and TCP port namespaces are totally independent, despite the fact that they are in the same numerical range.


1 Answers

There doesn't seem to be anything wrong with this code, but somewhere else your code seems to be calling accept() on the UDP socket, which isn't legal. All you need to do with a UDP socket is receive from it and send with it.

like image 76
user207421 Avatar answered Nov 02 '22 22:11

user207421