2013-05-21 15 views
5

Jak mogę przekonać Haskella do nasłuchu dla UDP i TCP na tym samym porcie?Nasłuchuj na TCP i UDP na tym samym porcie

Oto kod mam tak daleko (w oparciu o 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 kompiluje grzywny, ale pojawia się błąd obserwacji środowiska wykonawczego:

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

Niestety, dokumentację programowanie sieciowe w Haskell jest nieco ograniczone (jak zwykle). Naprawdę nie wiem, gdzie powinienem wyglądać, żeby wymyślić te rzeczy.

[UPDATE]
Dla każdego, kto jest zainteresowany, oto wynik:

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

Zdaję sobie sprawę, że jest dużo miejsca dla poprawy, ale to działa.

+3

Przydałaby się szczegółowa konfiguracja. Twój kod działa dobrze dla mnie na GHC 7.6.3 x86-64, Linux, używając sieci 2.4.1.2. Ponadto zbieranie dokumentacji jest niepotrzebne - sieć jest średnio dobrze udokumentowana, jest to w dużej mierze bezpośrednie wywołanie C, więc strony podręcznika są użyteczne, a pakiet jest na github, dzięki czemu możesz wysyłać poprawki. –

Odpowiedz

14

Nie wydaje się, że coś jest nie tak z tym kodem, ale gdzieś indziej Twój kod wydaje się wywoływać accept() na gnieździe UDP, co nie jest legalne. Wszystko, co musisz zrobić z gniazdem UDP, jest od niego odbierane i wysyłane razem z nim.

Powiązane problemy